From 29532c645821c5f1d66d51a28d75102b1207a932 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Thu, 16 Jun 2011 11:37:31 +0530 Subject: [PATCH 001/316] [EDI] first revision of specific import bzr revid: aar@tinyerp.com-20110616060731-rmp0eftd3hjlm3ep --- addons/account/__init__.py | 2 +- addons/account/__openerp__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account/__init__.py b/addons/account/__init__.py index 24129306e13..799f6fe08a5 100644 --- a/addons/account/__init__.py +++ b/addons/account/__init__.py @@ -34,5 +34,5 @@ import product import sequence import company import res_currency - +import edi_invoice # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index e4059896783..039a6800a98 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -143,7 +143,7 @@ module named account_voucher. 'test/account_bank_statement.yml', 'test/account_cash_statement.yml', 'test/account_report.yml', - + 'test/test_edi_invoice.yml', ], 'installable': True, From e26ae4e800d05e3e3045972cb234847c4e11ef82 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Tue, 21 Jun 2011 18:59:25 +0530 Subject: [PATCH 002/316] [EDI] refactor code of specific import bzr revid: aar@tinyerp.com-20110621132925-95jijdbuml3st9bo --- addons/account/__openerp__.py | 6 ++++-- addons/account/wizard/__init__.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 039a6800a98..07174e4971f 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -121,7 +121,9 @@ module named account_voucher. 'company_view.xml', 'board_account_view.xml', "wizard/account_report_profit_loss_view.xml", - "wizard/account_report_balance_sheet_view.xml" + "wizard/account_report_balance_sheet_view.xml", + 'test/test_edi_invoice.yml', + #'wizard/edi_import_view.xml', ], 'demo_xml': [ 'account_demo.xml', @@ -143,7 +145,7 @@ module named account_voucher. 'test/account_bank_statement.yml', 'test/account_cash_statement.yml', 'test/account_report.yml', - 'test/test_edi_invoice.yml', + ], 'installable': True, diff --git a/addons/account/wizard/__init__.py b/addons/account/wizard/__init__.py index caed6fc3977..0d888f8e712 100644 --- a/addons/account/wizard/__init__.py +++ b/addons/account/wizard/__init__.py @@ -65,6 +65,7 @@ import account_change_currency import account_report_balance_sheet import account_report_profit_loss + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From df0bbd0650db82a82711e601128d9b2a4b6ebfe1 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Tue, 21 Jun 2011 19:00:26 +0530 Subject: [PATCH 003/316] [EDI] refactor code of specific import bzr revid: aar@tinyerp.com-20110621133026-ll3afhk9qhwx52is --- addons/account/edi_invoice.py | 287 +++++++++++++++++++++++ addons/account/test/test_edi_invoice.yml | 13 + 2 files changed, 300 insertions(+) create mode 100644 addons/account/edi_invoice.py create mode 100644 addons/account/test/test_edi_invoice.yml diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py new file mode 100644 index 00000000000..956b0d9aa15 --- /dev/null +++ b/addons/account/edi_invoice.py @@ -0,0 +1,287 @@ + +from osv import fields, osv,orm +from base.ir import ir_edi + +class account_invoice(osv.osv,ir_edi.edi): + + _inherit = 'account.invoice' + #_name = 'edi.invoice' + + def edi_export(self, cr, uid, ids, edi_struct=None, context=None): + """Exports a supplier or customer invoice""" + rec_id = [ids[0].id] + + edi_struct = { + 'name': True, + 'origin': True, + 'company_id': True, # -> to be changed into partner + 'type': True, # -> reversed at import + 'internal_number': True, # -> reference at import + 'comment': True, + 'date_invoice': True, + 'date_due': True, + 'partner_id': True, + 'address_invoice_id': True, #only one address needed + 'payment_term': True, + 'currency_id': True, + 'invoice_line': { + 'name': True, + 'origin': True, + 'uos_id': True, + 'product_id': True, + 'price_unit': True, + 'quantity': True, + 'discount': True, + 'note': True, + }, + 'tax_line': { + 'name': True, + 'base': True, + 'amount': True, + 'manual': True, + 'sequence': True, + 'base_amount': True, + 'tax_amount': True, + }, + } + # Get EDI doc based on this struct. The result will also contain + # all metadata fields and attachments. + + edi_doc = super(account_invoice,self).edi_export(cr, uid, ids, edi_struct, context) + + + for i, invoice in enumerate(self.browse(cr, uid, rec_id, context=context)): + # add specific data for import + inv_comp = invoice.company_id + + + comp_partner = inv_comp.partner_id + + comp_partner_addr = comp_partner.address + + for address in comp_partner_addr: + + + edi_doc[i].update({ + # Add company info and address + 'company_address': { + 'street': address.street, + 'street2': address.street2, + 'zip': address.zip, + 'city': address.city, + 'state_id': self.edi_m2o(cr, uid, address.state_id), + 'country_id': self.edi_m2o(cr, uid, address.country_id), + 'email': address.email, + 'phone': address.phone + }, + # Function fields are not included in normal export + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + + return edi_doc + def edi_import(self, cr, uid, edi_document, context=None): + + """ During import, invoices will import the company that is provided in the invoice as + a new partner (e.g. supplier company for a customer invoice will be come a supplier + record for the new invoice. + Summary of tasks that need to be done: + - import company as a new partner, if type==in then supplier=1, else customer=1 + - partner_id field is modified to point to the new partner + - company_address data used to add address to new partner + - change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund' + - reference: should contain the value of the 'internal_number' + - reference_type: 'none' + - internal number: reset to False, auto-generated + - journal_id: should be selected based on type: simply put the 'type' + in the context when calling create(), will be selected correctly + - #payment_term: if set, create a default one based on name... + - 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 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. + """ + # generic implementation! + + partner = self.pool.get('res.partner') + partner_add = self.pool.get('res.partner.address') + model_data = self.pool.get('ir.model.data') + product_obj = self.pool.get('product.product') + product_categ = self.pool.get('product.category') + acc_invoice = self.pool.get('account.invoice') + company = self.pool.get('res.company') + tax_id = [] + account_id = [] + partner_id = None + company_id = None + if context is None: + context = {} + for field in edi_document.keys(): + + if field == 'type': + if len(edi_document['invoice_line']): + name = edi_document['invoice_line'][0]['product_id'][1] + else: + name = None + re_ids = product_obj.search(cr,uid,[('name','=',name)]) + if edi_document['type'] == 'out_invoice' or edi_document['type'] == 'out_refund': + if re_ids: + if product_obj.browse(cr,uid,re_ids)[0].property_account_expense: + account_id = product_obj.browse(cr,uid,re_ids)[0].property_account_expense + + else: + account_id = product_categ.browse(cr,uid,re_ids)[0].property_account_expense_categ + if product_obj.browse(cr,uid,re_ids)[0].taxes_id: + tax_id = product_obj.browse(cr, uid,re_ids)[0].taxes_id + if edi_document['type'] == 'out_refund': + edi_document['type'] = 'in_refund' + else: + edi_document['type'] = 'in_invoice' + + + elif edi_document['type'] == 'in_invoice' or edi_document['type'] == 'in_refund': + if re_ids: + if product_obj.browse(cr,uid,re_ids)[0].property_account_income: + account_id = product_obj.browse(cr,uid,re_ids)[0].property_account_income + else: + account_id = product_categ.browse(cr,uid,re_ids)[0].property_account_income_categ + if product_obj.browse(cr,uid,re_ids)[0].taxes_id: + tax_id = product_obj.browse(cr, uid,re_ids)[0].taxes_id + if edi_document['type'] == 'in_refund': + edi_document['type'] = 'out_refund' + else: + edi_document['type'] = 'out_invoice' + + if account_id: + name_ids = model_data.search(cr, uid, [('model','=',account_id._name),('res_id','=',account_id.id)]) + if name_ids: + xml_id = model_data.browse(cr, uid, name_ids)[0].name + db_uuid = ir_edi.safe_unique_id(account_id._name,account_id.id) + edi_document['invoice_line'][0]['account_id'] = [db_uuid+':'+xml_id,account_id.name] + + if tax_id: + name_ids = model_data.search(cr, uid, [('model','=',tax_id[0]._name),('res_id','=',tax_id[0].id)]) + + if name_ids: + xml_id = model_data.browse(cr, uid, name_ids)[0].name + db_uuid = ir_edi.safe_unique_id(tax_id[0]._name,tax_id[0].id) + edi_document['tax_line'][0]['account_id'] = [db_uuid+':'+xml_id,tax_id[0].name] + + else: + if len(edi_document['tax_line']): + edi_document['tax_line'][0]['manual'] = True + + res = {} + part = {} + comp = {} + partner_id = partner.search(cr,uid,[('name','=',edi_document['company_id'][1])]) + + if len(partner_id): + + browse_partner = partner.browse(cr,uid,partner_id[0]) + u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) + if len(u_id): + company_id = browse_partner.company_id + xml_obj = model_data.browse(cr,uid,u_id[0]) + uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) + db_uuid = '%s:%s' % (uuid,xml_obj.name) + part.update({'partner_id':[db_uuid,browse_partner.name]}) + + else: + company_id = company.create(cr, uid, {'name':edi_document['company_id'][1]}) + add_id = partner_add.create(cr,uid,edi_document['company_address']) + res.update({'name': edi_document['company_id'][1],'supplier': True, 'partner_id': edi_document['partner_id'],'address':add_id}) + partner_id = partner.create(cr,uid,res) + + browse_partner = partner.browse(cr,uid,partner_id[0]) + + u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) + + + if len(u_id): + + xml_obj = model_data.browse(cr,uid,u_id[0]) + uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) + db_uuid = '%s:%s' % (uuid,xml_obj.name) + part.update({'partner_id':[db_uuid,browse_partner.name]}) + + comp_id = partner.search(cr,uid,[('name','=',edi_document['partner_id'][1])]) + + if len(comp_id): + + browse_partner = partner.browse(cr,uid,comp_id[0]) + + browse_company = company.browse(cr,uid,browse_partner.company_id.id) + + u_id = u_id = model_data.search(cr, uid, [('res_id','=',browse_company.id),('model','=',browse_company._name)]) + if len(u_id): + + xml_obj = model_data.browse(cr,uid,u_id[0]) + uuid = ir_edi.safe_unique_id(browse_company._name,browse_company.id) + db_uuid = '%s:%s' % (uuid,xml_obj.name) + comp.update({'company_id':[db_uuid,browse_company.name]}) + + del edi_document['partner_id'] + del edi_document['company_id'] + edi_document.update(part) + edi_document.update(comp) + if len(partner_id): + + + + p = self.pool.get('res.partner').browse(cr, uid, partner_id[0]) + if company_id: + if p.property_account_receivable.company_id.id != company_id.id and p.property_account_payable.company_id.id != company_id.id: + property_obj = self.pool.get('ir.property') + + rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id.id)]) + pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id)]) + if not rec_pro_id: + rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('company_id','=',company_id.id)]) + if not pay_pro_id: + pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('company_id','=',company_id.id)]) + rec_line_data = property_obj.read(cr,uid,rec_pro_id,['name','value_reference','res_id']) + pay_line_data = property_obj.read(cr,uid,pay_pro_id,['name','value_reference','res_id']) + rec_res_id = rec_line_data and rec_line_data[0].get('value_reference',False) and int(rec_line_data[0]['value_reference'].split(',')[1]) or False + pay_res_id = pay_line_data and pay_line_data[0].get('value_reference',False) and int(pay_line_data[0]['value_reference'].split(',')[1]) or False + if not rec_res_id and not pay_res_id: + raise osv.except_osv(_('Configuration Error !'), + _('Can not find account chart for this company, Please Create account.')) + account_obj = self.pool.get('account.account') + rec_obj_acc = account_obj.browse(cr, uid, [rec_res_id]) + pay_obj_acc = account_obj.browse(cr, uid, [pay_res_id]) + p.property_account_receivable = rec_obj_acc[0] + p.property_account_payable = pay_obj_acc[0] + + if edi_document['type'] in ('out_invoice', 'out_refund'): + acc_obj = p.property_account_receivable + else: + acc_obj = p.property_account_payable + res_id = model_data.search(cr,uid,[('model','=',acc_obj._name),('res_id','=',acc_obj.id)]) + if len(res_id): + xml_obj = model_data.browse(cr, uid, res_id[0]) + uuid = ir_edi.safe_unique_id(acc_obj._name,acc_obj.id) + db_uuid = '%s:%s' % (uuid,xml_obj.name) + edi_document.update({'account_id':[db_uuid,acc_obj.name]}) + print "account_id",edi_document['account_id'] + edi_document.update({'reference':edi_document['internal_number'],'reference_type' : 'none'}) + edi_document['internal_number'] = False + context['type'] = edi_document['type'] + comp + del edi_document['company_address'] + + + return super(account_invoice,self).edi_import(cr, uid, edi_document) + +account_invoice() + +class account_invoice_line(osv.osv, ir_edi.edi): + _inherit='account.invoice.line' + +account_invoice_line() +class account_invoice_tax(osv.osv, ir_edi.edi): + _inherit = "account.invoice.tax" + +account_invoice_tax() diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml new file mode 100644 index 00000000000..af23dd3e57a --- /dev/null +++ b/addons/account/test/test_edi_invoice.yml @@ -0,0 +1,13 @@ +- + Tesing of Export functionality +- + !python {model: ir.edi.document}: | + invoice_obj = self.pool.get('account.invoice') + invoice_ids = invoice_obj.search(cr, uid, []) + print "invoices>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",invoice_ids + if invoice_ids: + invoices = invoice_obj.browse(cr, uid, invoice_ids) + tokens = self.export_edi(cr, uid, invoices) + for token in tokens: + document = self.get_document(cr, uid, token, context=context) + a = self.import_edi(cr, uid, edi_document = document) From 7f241bd2e7db48a791a65bc0ce83fd2d7cbf34ca Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Wed, 22 Jun 2011 14:44:25 +0530 Subject: [PATCH 004/316] [EDI] refactor code of specific edi import and export bzr revid: aar@tinyerp.com-20110622091425-b1ldh2oduyglaoa1 --- addons/account/__openerp__.py | 13 ++++++------ addons/account/edi_invoice.py | 39 ++++------------------------------- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 07174e4971f..b2996976c50 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -122,14 +122,13 @@ module named account_voucher. 'board_account_view.xml', "wizard/account_report_profit_loss_view.xml", "wizard/account_report_balance_sheet_view.xml", - 'test/test_edi_invoice.yml', - #'wizard/edi_import_view.xml', + ], 'demo_xml': [ - 'account_demo.xml', - 'project/project_demo.xml', - 'project/analytic_account_demo.xml', - 'demo/account_minimal.xml', + #'account_demo.xml', + #'project/project_demo.xml', + #'project/analytic_account_demo.xml', + #'demo/account_minimal.xml', # 'account_unit_test.xml', ], 'test': [ @@ -145,7 +144,7 @@ module named account_voucher. 'test/account_bank_statement.yml', 'test/account_cash_statement.yml', 'test/account_report.yml', - + 'test/test_edi_invoice.yml', ], 'installable': True, diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 956b0d9aa15..56d0e52df95 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -47,21 +47,13 @@ class account_invoice(osv.osv,ir_edi.edi): # Get EDI doc based on this struct. The result will also contain # all metadata fields and attachments. - edi_doc = super(account_invoice,self).edi_export(cr, uid, ids, edi_struct, context) - - + edi_doc = super(account_invoice,self).edi_export(cr, uid, ids, edi_struct, context) for i, invoice in enumerate(self.browse(cr, uid, rec_id, context=context)): # add specific data for import inv_comp = invoice.company_id - - comp_partner = inv_comp.partner_id - comp_partner_addr = comp_partner.address - for address in comp_partner_addr: - - edi_doc[i].update({ # Add company info and address 'company_address': { @@ -119,7 +111,6 @@ class account_invoice(osv.osv,ir_edi.edi): if context is None: context = {} for field in edi_document.keys(): - if field == 'type': if len(edi_document['invoice_line']): name = edi_document['invoice_line'][0]['product_id'][1] @@ -130,7 +121,6 @@ class account_invoice(osv.osv,ir_edi.edi): if re_ids: if product_obj.browse(cr,uid,re_ids)[0].property_account_expense: account_id = product_obj.browse(cr,uid,re_ids)[0].property_account_expense - else: account_id = product_categ.browse(cr,uid,re_ids)[0].property_account_expense_categ if product_obj.browse(cr,uid,re_ids)[0].taxes_id: @@ -138,9 +128,7 @@ class account_invoice(osv.osv,ir_edi.edi): if edi_document['type'] == 'out_refund': edi_document['type'] = 'in_refund' else: - edi_document['type'] = 'in_invoice' - - + edi_document['type'] = 'in_invoice' elif edi_document['type'] == 'in_invoice' or edi_document['type'] == 'in_refund': if re_ids: if product_obj.browse(cr,uid,re_ids)[0].property_account_income: @@ -163,12 +151,10 @@ class account_invoice(osv.osv,ir_edi.edi): if tax_id: name_ids = model_data.search(cr, uid, [('model','=',tax_id[0]._name),('res_id','=',tax_id[0].id)]) - if name_ids: xml_id = model_data.browse(cr, uid, name_ids)[0].name db_uuid = ir_edi.safe_unique_id(tax_id[0]._name,tax_id[0].id) edi_document['tax_line'][0]['account_id'] = [db_uuid+':'+xml_id,tax_id[0].name] - else: if len(edi_document['tax_line']): edi_document['tax_line'][0]['manual'] = True @@ -177,9 +163,7 @@ class account_invoice(osv.osv,ir_edi.edi): part = {} comp = {} partner_id = partner.search(cr,uid,[('name','=',edi_document['company_id'][1])]) - if len(partner_id): - browse_partner = partner.browse(cr,uid,partner_id[0]) u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) if len(u_id): @@ -188,20 +172,14 @@ class account_invoice(osv.osv,ir_edi.edi): uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) db_uuid = '%s:%s' % (uuid,xml_obj.name) part.update({'partner_id':[db_uuid,browse_partner.name]}) - else: company_id = company.create(cr, uid, {'name':edi_document['company_id'][1]}) add_id = partner_add.create(cr,uid,edi_document['company_address']) res.update({'name': edi_document['company_id'][1],'supplier': True, 'partner_id': edi_document['partner_id'],'address':add_id}) partner_id = partner.create(cr,uid,res) - browse_partner = partner.browse(cr,uid,partner_id[0]) - u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) - - if len(u_id): - xml_obj = model_data.browse(cr,uid,u_id[0]) uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) db_uuid = '%s:%s' % (uuid,xml_obj.name) @@ -210,14 +188,10 @@ class account_invoice(osv.osv,ir_edi.edi): comp_id = partner.search(cr,uid,[('name','=',edi_document['partner_id'][1])]) if len(comp_id): - browse_partner = partner.browse(cr,uid,comp_id[0]) - browse_company = company.browse(cr,uid,browse_partner.company_id.id) - u_id = u_id = model_data.search(cr, uid, [('res_id','=',browse_company.id),('model','=',browse_company._name)]) if len(u_id): - xml_obj = model_data.browse(cr,uid,u_id[0]) uuid = ir_edi.safe_unique_id(browse_company._name,browse_company.id) db_uuid = '%s:%s' % (uuid,xml_obj.name) @@ -228,9 +202,6 @@ class account_invoice(osv.osv,ir_edi.edi): edi_document.update(part) edi_document.update(comp) if len(partner_id): - - - p = self.pool.get('res.partner').browse(cr, uid, partner_id[0]) if company_id: if p.property_account_receivable.company_id.id != company_id.id and p.property_account_payable.company_id.id != company_id.id: @@ -265,14 +236,12 @@ class account_invoice(osv.osv,ir_edi.edi): uuid = ir_edi.safe_unique_id(acc_obj._name,acc_obj.id) db_uuid = '%s:%s' % (uuid,xml_obj.name) edi_document.update({'account_id':[db_uuid,acc_obj.name]}) - print "account_id",edi_document['account_id'] + edi_document.update({'reference':edi_document['internal_number'],'reference_type' : 'none'}) edi_document['internal_number'] = False context['type'] = edi_document['type'] - comp + del edi_document['company_address'] - - return super(account_invoice,self).edi_import(cr, uid, edi_document) account_invoice() From 1d98e87dcca53ad9b89007d602734ec1b629821f Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Wed, 22 Jun 2011 15:44:47 +0530 Subject: [PATCH 005/316] [EDI] revised code of specific import and export bzr revid: aar@tinyerp.com-20110622101447-qm824uxvcedyjgd4 --- addons/account/__openerp__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index b2996976c50..651c426dc80 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -125,10 +125,10 @@ module named account_voucher. ], 'demo_xml': [ - #'account_demo.xml', - #'project/project_demo.xml', - #'project/analytic_account_demo.xml', - #'demo/account_minimal.xml', + 'account_demo.xml', + 'project/project_demo.xml', + 'project/analytic_account_demo.xml', + 'demo/account_minimal.xml', # 'account_unit_test.xml', ], 'test': [ From 77b2a20d81980235353b5e33f7b8897bfbe355b9 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Thu, 23 Jun 2011 19:12:07 +0530 Subject: [PATCH 006/316] [EDI]:customer invoice testing through yml bzr revid: aar@tinyerp.com-20110623134207-soeh9tgaknfhp6hf --- addons/account/__openerp__.py | 3 +- addons/account/test/test_edi_invoice.yml | 64 ++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 651c426dc80..1bb1b56a476 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -122,8 +122,7 @@ module named account_voucher. 'board_account_view.xml', "wizard/account_report_profit_loss_view.xml", "wizard/account_report_balance_sheet_view.xml", - - ], + ], 'demo_xml': [ 'account_demo.xml', 'project/project_demo.xml', diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index af23dd3e57a..9d624489c8c 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -1,13 +1,71 @@ - - Tesing of Export functionality + create Company +- + !record {model: res.company, id: res_company_test}: + name: Thomson pvt. ltd. + partner_id: 1 + rml_header: 1 + rml_header2: 1 + rml_header3: 1 + currency_id: 1 + +- + create customer +- + !record {model: res.partner, id: res_partner_test}: + name: Junjun wala + supplier: False + company_id: res_company_test + address: + - partner_id: res_partner_test + type: default + name: ivan + street: m g road + street2: line 28 + city: paris + +- + Creating a customer invoice record +- + !record {model: account.invoice, id: account_invoice_test}: + amount_tax: 0.0 + amount_total: 83.0 + amount_untaxed: 83.0 + currency_id: base.EUR + date_invoice: '2011-06-22' + invoice_line: + name: '[CPU1] Processor AMD Athlon XP 1800+' + partner_id: res_partner_test + price_subtotal: 75.0 + price_unit: 75.0 + product_id: product.product_product_cpu1 + quantity: 1.0 + journal_id: 'False' + name: Nothing + partner_id: res_partner_test + payment_term: account.account_payment_term + reference_type: none + +- + Tesing of Export functionality and Import Functionality - !python {model: ir.edi.document}: | + invoice_obj = self.pool.get('account.invoice') - invoice_ids = invoice_obj.search(cr, uid, []) - print "invoices>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",invoice_ids + invoice_ids = invoice_obj.search(cr, uid, [partner_id]) if invoice_ids: invoices = invoice_obj.browse(cr, uid, invoice_ids) tokens = self.export_edi(cr, uid, invoices) for token in tokens: document = self.get_document(cr, uid, token, context=context) a = self.import_edi(cr, uid, edi_document = document) + +- + Check after import of document customer become supplier or not +- + !python {model: account.invoice}: | + ids=self.search(cr, uid, [('partner_id','=',base.main_company),('company_id','=',res_company_test),('type','=','in_invoice')]) + if not ids: + raise AssertionError("Invoice is not imported") + + \ No newline at end of file From 66356f01af42f48df61064ae1fc5ff1f0453de92 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Fri, 24 Jun 2011 18:41:17 +0530 Subject: [PATCH 007/316] [EDI] Final Tesing Ymal bzr revid: aar@tinyerp.com-20110624131117-x517otc1yc1f2r97 --- addons/account/__openerp__.py | 1 + addons/account/edi_invoice.py | 60 ++++++++++++++++--- addons/account/test/test_edi_invoice.yml | 76 +++++++++++------------- 3 files changed, 86 insertions(+), 51 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 1bb1b56a476..44537ad638a 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -122,6 +122,7 @@ module named account_voucher. 'board_account_view.xml', "wizard/account_report_profit_loss_view.xml", "wizard/account_report_balance_sheet_view.xml", + ], 'demo_xml': [ 'account_demo.xml', diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 56d0e52df95..189604e6306 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -1,6 +1,7 @@ -from osv import fields, osv,orm +from osv import fields, osv, orm from base.ir import ir_edi +from tools.translate import _ class account_invoice(osv.osv,ir_edi.edi): @@ -96,6 +97,7 @@ class account_invoice(osv.osv,ir_edi.edi): on the tax config of the DB where it is imported. """ # generic implementation! + "" partner = self.pool.get('res.partner') partner_add = self.pool.get('res.partner.address') @@ -104,6 +106,7 @@ class account_invoice(osv.osv,ir_edi.edi): product_categ = self.pool.get('product.category') acc_invoice = self.pool.get('account.invoice') company = self.pool.get('res.company') + country = self.pool.get('res.country') tax_id = [] account_id = [] partner_id = None @@ -168,16 +171,47 @@ class account_invoice(osv.osv,ir_edi.edi): u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) if len(u_id): company_id = browse_partner.company_id + xml_obj = model_data.browse(cr,uid,u_id[0]) uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) db_uuid = '%s:%s' % (uuid,xml_obj.name) part.update({'partner_id':[db_uuid,browse_partner.name]}) + else: + + company_address = {} company_id = company.create(cr, uid, {'name':edi_document['company_id'][1]}) - add_id = partner_add.create(cr,uid,edi_document['company_address']) - res.update({'name': edi_document['company_id'][1],'supplier': True, 'partner_id': edi_document['partner_id'],'address':add_id}) - partner_id = partner.create(cr,uid,res) + + for key in edi_document['company_address'].keys(): + if type(edi_document['company_address'][key]).__name__ == 'list': + if edi_document['company_address'][key][1] is not None: + country_id = country.search(cr ,uid,[('name','=',edi_document['company_address'][key][1])]) + + if len(country_id): + company_address.update({key : country_id[0]}) + + else: + if isinstance(edi_document['company_address'][key][1],unicode): + country_name = str(edi_document['company_address'][key][1]) + country_code = country_name[:2].upper() + country_id = country.create(cr, uid, {'code': country_code,name: country_name}) + company_address.update({key : country_id[0]}) + else: + company_address.update({key : edi_document['company_address'][key][1]}) + else: + company_address.update({key:edi_document['company_address'][key]}) + + add_id = [] + partner_id = [] + + add_id = partner_add.create(cr,uid,company_address) + + res.update({'name': edi_document['company_id'][1],'supplier': True,'address': [unicode(add_id)], 'company_id': unicode(company_id),'country' : country_id}) + + partner_id.append(partner.create(cr,uid,{'name': edi_document['company_id'][1],'supplier': True,'address': unicode(add_id), 'company_id': unicode(company_id),'country' : country_id})) + browse_partner = partner.browse(cr,uid,partner_id[0]) + company_id = browse_partner.company_id u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) if len(u_id): xml_obj = model_data.browse(cr,uid,u_id[0]) @@ -200,15 +234,21 @@ class account_invoice(osv.osv,ir_edi.edi): del edi_document['partner_id'] del edi_document['company_id'] edi_document.update(part) - edi_document.update(comp) + edi_document.update(comp) + + if len(partner_id): p = self.pool.get('res.partner').browse(cr, uid, partner_id[0]) + + partner_id = int(partner_id[0]) + if company_id: if p.property_account_receivable.company_id.id != company_id.id and p.property_account_payable.company_id.id != company_id.id: property_obj = self.pool.get('ir.property') rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id.id)]) - pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id)]) + pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id.id)]) + if not rec_pro_id: rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('company_id','=',company_id.id)]) if not pay_pro_id: @@ -218,8 +258,8 @@ class account_invoice(osv.osv,ir_edi.edi): rec_res_id = rec_line_data and rec_line_data[0].get('value_reference',False) and int(rec_line_data[0]['value_reference'].split(',')[1]) or False pay_res_id = pay_line_data and pay_line_data[0].get('value_reference',False) and int(pay_line_data[0]['value_reference'].split(',')[1]) or False if not rec_res_id and not pay_res_id: - raise osv.except_osv(_('Configuration Error !'), - _('Can not find account chart for this company, Please Create account.')) + raise osv.except_osv(_('Configuration Error !'), _('Can not find account chart for this company, Please Create account.')) + account_obj = self.pool.get('account.account') rec_obj_acc = account_obj.browse(cr, uid, [rec_res_id]) pay_obj_acc = account_obj.browse(cr, uid, [pay_res_id]) @@ -230,7 +270,9 @@ class account_invoice(osv.osv,ir_edi.edi): acc_obj = p.property_account_receivable else: acc_obj = p.property_account_payable + res_id = model_data.search(cr,uid,[('model','=',acc_obj._name),('res_id','=',acc_obj.id)]) + if len(res_id): xml_obj = model_data.browse(cr, uid, res_id[0]) uuid = ir_edi.safe_unique_id(acc_obj._name,acc_obj.id) @@ -240,7 +282,7 @@ class account_invoice(osv.osv,ir_edi.edi): edi_document.update({'reference':edi_document['internal_number'],'reference_type' : 'none'}) edi_document['internal_number'] = False context['type'] = edi_document['type'] - + del edi_document['company_address'] return super(account_invoice,self).edi_import(cr, uid, edi_document) diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index 9d624489c8c..ec0dead338c 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -1,7 +1,7 @@ - create Company - - !record {model: res.company, id: res_company_test}: + !record {model: res.company, id: res_company_test11}: name: Thomson pvt. ltd. partner_id: 1 rml_header: 1 @@ -10,62 +10,54 @@ currency_id: 1 - - create customer + create partner - - !record {model: res.partner, id: res_partner_test}: + !record {model: res.partner, id: res_partner_test20}: name: Junjun wala supplier: False - company_id: res_company_test - address: - - partner_id: res_partner_test - type: default - name: ivan - street: m g road - street2: line 28 - city: paris + company_id: res_company_test11 -- - Creating a customer invoice record -- - !record {model: account.invoice, id: account_invoice_test}: - amount_tax: 0.0 - amount_total: 83.0 - amount_untaxed: 83.0 +- + create customer invoice +- + !record {model: account.invoice, id: customer_invoice_test}: + journal_id: 1 + partner_id: res_partner_test20 currency_id: base.EUR + address_invoice_id: base.res_partner_address_11 + company_id: base.main_company + account_id: 1 date_invoice: '2011-06-22' - invoice_line: - name: '[CPU1] Processor AMD Athlon XP 1800+' - partner_id: res_partner_test - price_subtotal: 75.0 - price_unit: 75.0 - product_id: product.product_product_cpu1 - quantity: 1.0 - journal_id: 'False' name: Nothing - partner_id: res_partner_test - payment_term: account.account_payment_term - reference_type: none - + 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 + name: 'basic pc' + account_id: 1 + - Tesing of Export functionality and Import Functionality - !python {model: ir.edi.document}: | invoice_obj = self.pool.get('account.invoice') - invoice_ids = invoice_obj.search(cr, uid, [partner_id]) - if invoice_ids: - invoices = invoice_obj.browse(cr, uid, invoice_ids) - tokens = self.export_edi(cr, uid, invoices) - for token in tokens: - document = self.get_document(cr, uid, token, context=context) - a = self.import_edi(cr, uid, edi_document = document) - + #invoice_ids = invoice_obj.search(cr, uid, ['account.customer_invoice_test']) + #if invoice_ids: + invoices = invoice_obj.browse(cr, uid, [ref("customer_invoice_test")]) + tokens = self.export_edi(cr, uid, invoices) + for token in tokens: + document = self.get_document(cr, uid, token, context=context) + a = self.import_edi(cr, uid, edi_document = document) + - - Check after import of document customer become supplier or not + Check the customer invoice is exported or not - !python {model: account.invoice}: | - ids=self.search(cr, uid, [('partner_id','=',base.main_company),('company_id','=',res_company_test),('type','=','in_invoice')]) + ids=self.search(cr, uid, [('partner_id','=',ref("res_partner_test20")),('company_id','=',ref("res_company_test11")),('type','=','out_invoice')]) if not ids: raise AssertionError("Invoice is not imported") - - \ No newline at end of file + From b2f73c0010ae84da417906a28300120b3571eec6 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 27 Jun 2011 14:02:28 +0530 Subject: [PATCH 008/316] [REVIEW+IMP] account, EDI: clean export_edi method of account.invoice bzr revid: hmo@tinyerp.com-20110627083228-cmiuptih2y8kjlqd --- addons/account/__openerp__.py | 5 +- addons/account/edi_invoice.py | 78 ++++++++++++++---------- addons/account/test/test_edi_invoice.yml | 1 + 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 44537ad638a..5ec724ed462 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -143,10 +143,9 @@ module named account_voucher. 'test/account_fiscalyear_close.yml', 'test/account_bank_statement.yml', 'test/account_cash_statement.yml', - 'test/account_report.yml', 'test/test_edi_invoice.yml', - - ], + 'test/account_report.yml', + ], 'installable': True, 'active': False, 'certificate': '0080331923549', diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 7020a8115ad..ba3675a15f4 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -23,13 +23,11 @@ from osv import fields, osv, orm from base.ir import ir_edi from tools.translate import _ -class account_invoice(osv.osv,ir_edi.edi): +class account_invoice(osv.osv, ir_edi.edi): _inherit = 'account.invoice' - def edi_export(self, cr, uid, ids, edi_struct=None, context=None): + def edi_export(self, cr, uid, records, edi_struct=None, context=None): """Exports a supplier or customer invoice""" - rec_id = [ids[0].id] - edi_struct = { 'name': True, 'origin': True, @@ -63,35 +61,51 @@ class account_invoice(osv.osv,ir_edi.edi): 'tax_amount': True, }, } - # Get EDI doc based on this struct. The result will also contain - # all metadata fields and attachments. - - edi_doc = super(account_invoice,self).edi_export(cr, uid, ids, edi_struct, context) - for i, invoice in enumerate(self.browse(cr, uid, rec_id, context=context)): - # add specific data for import - inv_comp = invoice.company_id - comp_partner = inv_comp.partner_id - comp_partner_addr = comp_partner.address - for address in comp_partner_addr: - edi_doc[i].update({ - # Add company info and address - 'company_address': { - 'street': address.street, - 'street2': address.street2, - 'zip': address.zip, - 'city': address.city, - 'state_id': self.edi_m2o(cr, uid, address.state_id), - 'country_id': self.edi_m2o(cr, uid, address.country_id), - 'email': address.email, - 'phone': address.phone - }, - # Function fields are not included in normal export + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + company_address_dict = { + 'street': True, + 'street2': True, + 'zip': True, + 'city': True, + 'state_id': True, + 'country_id': True, + 'email': True, + 'phone': True, + + } + 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] - #'company_logo': inv_comp.logo,#TODO - #'paid': inv_comp.paid, #TODO - }) - - return edi_doc + # Add company info and address + res = partner_pool.address_get(cr, uid, [invoice.company_id.partner_id.id], ['contact', 'invoice']) + contact_addr_id = res['contact'] + invoice_addr_id = res['invoice'] + + address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) + edi_company_address_dict = {} + for key, value in company_address_dict.items(): + if not value: + continue + address_rec = getattr(address, key) + if not address_rec: + continue + if key.endswith('_id'): + address_rec = self.edi_m2o(cr, uid, address_rec, context=context) + edi_company_address_dict[key] = address_rec + + edi_doc.update({ + 'company_address': edi_company_address_dict, + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + edi_doc_list.append(edi_doc) + return edi_doc_list def edi_import(self, cr, uid, edi_document, context=None): diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index 75c39d8aaf0..f66932f0464 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -48,6 +48,7 @@ tokens = self.export_edi(cr, uid, invoices) for token in tokens: document = self.get_document(cr, uid, token, context=context) + print document a = self.import_edi(cr, uid, edi_document = document) - From 3154cb96520b6a279e95f5cde74b5005cee472ab Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 27 Jun 2011 17:56:16 +0530 Subject: [PATCH 009/316] [REF] account, edi: refactor code of edi_import method bzr revid: hmo@tinyerp.com-20110627122616-15e6y17d29bbricb --- addons/account/edi_invoice.py | 295 +++++++++-------------- addons/account/test/test_edi_invoice.yml | 5 +- 2 files changed, 119 insertions(+), 181 deletions(-) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index ba3675a15f4..5d6d92df584 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -131,192 +131,131 @@ class account_invoice(osv.osv, ir_edi.edi): on the tax config of the DB where it is imported. """ - partner = self.pool.get('res.partner') - partner_add = self.pool.get('res.partner.address') - model_data = self.pool.get('ir.model.data') - product_obj = self.pool.get('product.product') - product_categ = self.pool.get('product.category') - acc_invoice = self.pool.get('account.invoice') - company = self.pool.get('res.company') - country = self.pool.get('res.country') + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + model_data_pool = self.pool.get('ir.model.data') + product_pool = self.pool.get('product.product') + product_categ_pool = self.pool.get('product.category') + company_pool = self.pool.get('res.company') + country_pool = self.pool.get('res.country') + state_pool = self.pool.get('res.country.state') + account_journal_pool = self.pool.get('account.journal') + invoice_line_pool = self.pool.get('account.invoice.line') + account_pool = self.pool.get('account.account') tax_id = [] account_id = [] partner_id = None company_id = None if context is None: context = {} - for field in edi_document.keys(): - if field == 'type': - if len(edi_document['invoice_line']): - name = edi_document['invoice_line'][0]['product_id'][1] - else: - name = None - re_ids = product_obj.search(cr,uid,[('name','=',name)]) - if edi_document['type'] == 'out_invoice' or edi_document['type'] == 'out_refund': - if re_ids: - if product_obj.browse(cr,uid,re_ids)[0].property_account_expense: - account_id = product_obj.browse(cr,uid,re_ids)[0].property_account_expense - else: - account_id = product_categ.browse(cr,uid,re_ids)[0].property_account_expense_categ - if product_obj.browse(cr,uid,re_ids)[0].taxes_id: - tax_id = product_obj.browse(cr, uid,re_ids)[0].taxes_id - if edi_document['type'] == 'out_refund': - edi_document['type'] = 'in_refund' - else: - edi_document['type'] = 'in_invoice' - elif edi_document['type'] == 'in_invoice' or edi_document['type'] == 'in_refund': - if re_ids: - if product_obj.browse(cr,uid,re_ids)[0].property_account_income: - account_id = product_obj.browse(cr,uid,re_ids)[0].property_account_income - else: - account_id = product_categ.browse(cr,uid,re_ids)[0].property_account_income_categ - if product_obj.browse(cr,uid,re_ids)[0].taxes_id: - tax_id = product_obj.browse(cr, uid,re_ids)[0].taxes_id - if edi_document['type'] == 'in_refund': - edi_document['type'] = 'out_refund' - else: - edi_document['type'] = 'out_invoice' - - if account_id: - name_ids = model_data.search(cr, uid, [('model','=',account_id._name),('res_id','=',account_id.id)]) - if name_ids: - xml_id = model_data.browse(cr, uid, name_ids)[0].name - db_uuid = ir_edi.safe_unique_id(account_id._name,account_id.id) - edi_document['invoice_line'][0]['account_id'] = [db_uuid+':'+xml_id,account_id.name] - - if tax_id: - name_ids = model_data.search(cr, uid, [('model','=',tax_id[0]._name),('res_id','=',tax_id[0].id)]) - if name_ids: - xml_id = model_data.browse(cr, uid, name_ids)[0].name - db_uuid = ir_edi.safe_unique_id(tax_id[0]._name,tax_id[0].id) - edi_document['tax_line'][0]['account_id'] = [db_uuid+':'+xml_id,tax_id[0].name] - else: - if len(edi_document['tax_line']): - edi_document['tax_line'][0]['manual'] = True - - res = {} - part = {} - comp = {} - partner_id = partner.search(cr,uid,[('name','=',edi_document['company_id'][1])]) - if len(partner_id): - browse_partner = partner.browse(cr,uid,partner_id[0]) - u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) - if len(u_id): - company_id = browse_partner.company_id - - xml_obj = model_data.browse(cr,uid,u_id[0]) - uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) - db_uuid = '%s:%s' % (uuid,xml_obj.name) - part.update({'partner_id':[db_uuid,browse_partner.name]}) - - else: - - company_address = {} - company_id = company.create(cr, uid, {'name':edi_document['company_id'][1]}) - - for key in edi_document['company_address'].keys(): - if type(edi_document['company_address'][key]).__name__ == 'list': - if edi_document['company_address'][key][1] is not None: - country_id = country.search(cr ,uid,[('name','=',edi_document['company_address'][key][1])]) - - if len(country_id): - company_address.update({key : country_id[0]}) - - else: - if isinstance(edi_document['company_address'][key][1],unicode): - country_name = str(edi_document['company_address'][key][1]) - country_code = country_name[:2].upper() - country_id = country.create(cr, uid, {'code': country_code,name: country_name}) - company_address.update({key : country_id[0]}) - else: - company_address.update({key : edi_document['company_address'][key][1]}) - else: - company_address.update({key:edi_document['company_address'][key]}) - - add_id = [] - partner_id = [] - - add_id = partner_add.create(cr,uid,company_address) - - res.update({'name': edi_document['company_id'][1],'supplier': True,'address': [unicode(add_id)], 'company_id': unicode(company_id),'country' : country_id}) - - partner_id.append(partner.create(cr,uid,{'name': edi_document['company_id'][1],'supplier': True,'address': unicode(add_id), 'company_id': unicode(company_id),'country' : country_id})) - - browse_partner = partner.browse(cr,uid,partner_id[0]) - company_id = browse_partner.company_id - u_id = model_data.search(cr, uid, [('res_id','=',browse_partner.id),('model','=',browse_partner._name)]) - if len(u_id): - xml_obj = model_data.browse(cr,uid,u_id[0]) - uuid = ir_edi.safe_unique_id(browse_partner._name,browse_partner.id) - db_uuid = '%s:%s' % (uuid,xml_obj.name) - part.update({'partner_id':[db_uuid,browse_partner.name]}) - - comp_id = partner.search(cr,uid,[('name','=',edi_document['partner_id'][1])]) - - if len(comp_id): - browse_partner = partner.browse(cr,uid,comp_id[0]) - browse_company = company.browse(cr,uid,browse_partner.company_id.id) - u_id = u_id = model_data.search(cr, uid, [('res_id','=',browse_company.id),('model','=',browse_company._name)]) - if len(u_id): - xml_obj = model_data.browse(cr,uid,u_id[0]) - uuid = ir_edi.safe_unique_id(browse_company._name,browse_company.id) - db_uuid = '%s:%s' % (uuid,xml_obj.name) - comp.update({'company_id':[db_uuid,browse_company.name]}) - - del edi_document['partner_id'] - del edi_document['company_id'] - edi_document.update(part) - edi_document.update(comp) - - - if len(partner_id): - p = self.pool.get('res.partner').browse(cr, uid, partner_id[0]) - - partner_id = int(partner_id[0]) - - if company_id: - if p.property_account_receivable.company_id.id != company_id.id and p.property_account_payable.company_id.id != company_id.id: - property_obj = self.pool.get('ir.property') - - rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id.id)]) - pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('res_id','=','res.partner,'+str(partner_id)+''),('company_id','=',company_id.id)]) - - if not rec_pro_id: - rec_pro_id = property_obj.search(cr,uid,[('name','=','property_account_receivable'),('company_id','=',company_id.id)]) - if not pay_pro_id: - pay_pro_id = property_obj.search(cr,uid,[('name','=','property_account_payable'),('company_id','=',company_id.id)]) - rec_line_data = property_obj.read(cr,uid,rec_pro_id,['name','value_reference','res_id']) - pay_line_data = property_obj.read(cr,uid,pay_pro_id,['name','value_reference','res_id']) - rec_res_id = rec_line_data and rec_line_data[0].get('value_reference',False) and int(rec_line_data[0]['value_reference'].split(',')[1]) or False - pay_res_id = pay_line_data and pay_line_data[0].get('value_reference',False) and int(pay_line_data[0]['value_reference'].split(',')[1]) or False - if not rec_res_id and not pay_res_id: - raise osv.except_osv(_('Configuration Error !'), _('Can not find account chart for this company, Please Create account.')) - - account_obj = self.pool.get('account.account') - rec_obj_acc = account_obj.browse(cr, uid, [rec_res_id]) - pay_obj_acc = account_obj.browse(cr, uid, [pay_res_id]) - p.property_account_receivable = rec_obj_acc[0] - p.property_account_payable = pay_obj_acc[0] - if edi_document['type'] in ('out_invoice', 'out_refund'): - acc_obj = p.property_account_receivable - else: - acc_obj = p.property_account_payable - - res_id = model_data.search(cr,uid,[('model','=',acc_obj._name),('res_id','=',acc_obj.id)]) - - if len(res_id): - xml_obj = model_data.browse(cr, uid, res_id[0]) - uuid = ir_edi.safe_unique_id(acc_obj._name,acc_obj.id) - db_uuid = '%s:%s' % (uuid,xml_obj.name) - edi_document.update({'account_id':[db_uuid,acc_obj.name]}) - - edi_document.update({'reference':edi_document['internal_number'],'reference_type' : 'none'}) - edi_document['internal_number'] = False - context['type'] = edi_document['type'] - + + # import company as a new partner, if type==in then supplier=1, else customer=1 + # partner_id field is modified to point to the new partner + # company_address data used to add address to new partner + edi_company_address = edi_document['company_address'] + edi_partner_id = edi_document['partner_id'] + company_name = edi_document['company_id'][1] + invoice_type = edi_document['type'] + state_id = edi_company_address.get('state_id', False) + state_name = state_id and state_id[1] + country_id = edi_company_address.get('country_id', False) + country_name = country_id and country_id[1] + + country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False + state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, + values={'country_id': country_id, 'code': state_name}, context=context) or False + address_value = { + 'street': edi_company_address.get('street', False), + 'street2': edi_company_address.get('street2', False), + 'zip': edi_company_address.get('zip', False), + 'city': edi_company_address.get('city', False), + 'state_id': state_id, + 'country_id': country_id, + 'email': edi_company_address.get('email', False), + 'phone': edi_company_address.get('phone', False), + + } + + + partner_value = {'name': company_name} + if invoice_type in ('out_invoice', 'in_refund'): + partner_value.update({'customer': True, 'supplier': False}) + if invoice_type in ('in_invoice', 'out_refund'): + partner_value.update({'customer': False, 'supplier': True}) + + partner_id = partner_pool.create(cr, uid, partner_value, context=context) + address_value.update({'partner_id': partner_id}) + address_id = partner_address_pool.create(cr, uid, address_value, context=context) + + partner = partner_pool.browse(cr, uid, partner_id, context=context) + edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) + + # change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund' + invoice_type = invoice_type.startswith('in_') and invoice_type.replace('in_','out_') or invoice_type.replace('out_','in_') + edi_document['type'] = invoice_type + + # Set Account + if invoice_type in ('out_invoice', 'out_refund'): + invoice_account = partner.property_account_receivable + else: + invoice_account = partner.property_account_payable + 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' + edi_document['reference'] = edi_document.get('internal_number', False) + # reference_type: 'none' + edi_document['reference_type'] = 'none' + + # internal number: reset to False, auto-generated + edi_document['internal_number'] = False + + # company should set by default so delete company data from edi Document del edi_document['company_address'] - return super(account_invoice,self).edi_import(cr, uid, edi_document) + del edi_document['company_id'] + + # journal_id: should be selected based on type: simply put the 'type' in the context when calling create(), will be selected correctly + 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) + edi_document['journal_id'] = journal and self.edi_m2o(cr, uid, journal, context=context) or False + + # 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) + product = product_pool.browse(cr, uid, product_id, context=context) + + 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 + else: + account = product.product_tmpl_id.property_account_expense + if not account: + account = product.categ_id.property_account_expense_categ + + # TODO: add effect of fiscal position + # 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 + + # 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. + for edi_tax_line in edi_document.get('tax_line', []): + account_ids = account_pool.search(cr, uid, [('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]) + if account_ids: + edi_tax_line['account_id'] = account_ids[0] #TODO should select account of output VAT for Customer Invoice and Input VAT for Supplier Invoice + edi_tax_line['manual'] = True + + # TODO :=> payment_term: if set, create a default one based on name... + print edi_document + return super(account_invoice,self).edi_import(cr, uid, edi_document, context=context) account_invoice() diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index f66932f0464..18e5a8fb9e9 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -28,7 +28,7 @@ company_id: base.main_company account_id: 1 date_invoice: '2011-06-22' - name: Nothing + name: selling product type: 'out_invoice' invoice_line: - product_id: product.product_product_pc1 @@ -48,14 +48,13 @@ tokens = self.export_edi(cr, uid, invoices) for token in tokens: document = self.get_document(cr, uid, token, context=context) - print document a = self.import_edi(cr, uid, edi_document = document) - Check the customer invoice is exported or not - !python {model: account.invoice}: | - ids=self.search(cr, uid, [('partner_id','=',ref("res_partner_test20")),('company_id','=',ref("res_company_test11")),('type','=','out_invoice')]) + ids=self.search(cr, uid, [('partner_id','=',ref("res_partner_test20")),('type','=','out_invoice')]) if not ids: raise AssertionError("Invoice is not imported") From 99624f6b0efe76186d1c51e26d733938c087660d Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 27 Jun 2011 17:57:32 +0530 Subject: [PATCH 010/316] [REF] account, edi: remove print statement bzr revid: hmo@tinyerp.com-20110627122732-s2yswh7mtyaumjz9 --- addons/account/edi_invoice.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 5d6d92df584..e37bd220d35 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -254,7 +254,6 @@ class account_invoice(osv.osv, ir_edi.edi): edi_tax_line['manual'] = True # TODO :=> payment_term: if set, create a default one based on name... - print edi_document return super(account_invoice,self).edi_import(cr, uid, edi_document, context=context) account_invoice() From 0441c97c5c8eef5809cf9a6dfc8982ca9e6f8d8b Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 29 Jun 2011 11:14:52 +0530 Subject: [PATCH 011/316] [REVIEW] account: correct YML of EDI bzr revid: hmo@tinyerp.com-20110629054452-2e0vsmleaouos6zv --- addons/account/test/test_edi_invoice.yml | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index dacd80e57b1..6651448c712 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -1,5 +1,5 @@ - - create Company + I create a company for Customer - !record {model: res.company, id: res_company_test11}: name: Thomson pvt. ltd. @@ -10,14 +10,14 @@ currency_id: 1 - - create partner + 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 - - create customer invoice + I create one customer invoice - !record {model: account.invoice, id: customer_invoice_test}: journal_id: 1 @@ -45,7 +45,7 @@ amount: 1000.00 - - I open the Invoice for the SO. + I Open the Invoice - !python {model: account.invoice}: | @@ -55,30 +55,30 @@ wf_service.trg_validate(uid, 'account.invoice',invoices.id,'invoice_open', cr) - - Tesing of EDI functionality + I Tesing of EDI functionality. First I export customer invoice from my company than import that invoice into customer company - !python {model: ir.edi.document}: | - invoice_invoice_new = self.pool.get('account.invoice') - invoices = invoice_invoice_new.browse(cr, uid, [ref("customer_invoice_test")]) - tokens = self.export_edi(cr, uid, invoices) - for token in tokens: - document = self.get_document(cr, uid, token, context=context) - a = self.import_edi(cr, uid, edi_document = 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' + document = self.get_document(cr, uid, tokens[0]) + a = self.import_edi(cr, uid, edi_document = document) + assert a, 'Invoice is not imported' - - Check the exported out_invoice become in_invoice or not + I Checking the out invoice become in invoice or not after import - !python {model: account.invoice}: | - invoice_old = self.browse(cr,uid,ref("customer_invoice_test")) + invoice_old = self.browse(cr, uid, ref("customer_invoice_test")) new_partner_id = self.pool.get('res.partner').name_search(cr, uid, invoice_old.company_id.name) - assert new_partner_id, 'Partner is not created of party' + assert new_partner_id, 'Partner is not created of Supplier' - ids = self.search(cr, uid, [('partner_id','=',new_partner_id[0]),('reference','=',invoice_old.internal_number)]) + ids = self.search(cr, uid, [('partner_id','=',new_partner_id[0][0]),('reference','=',invoice_old.internal_number)]) assert ids, 'Invoice does not have created of party' invoice_new = self.browse(cr, uid, ids[0]) assert invoice_new.reference == invoice_old.internal_number, "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" for inv_line in invoice_new.invoice_line: From d1ce89e2a5f2fb26fdc93fc461859329a9329ff0 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Fri, 8 Jul 2011 15:00:22 +0530 Subject: [PATCH 012/316] [IMP]:Adding stock picking in edi bzr revid: han@tinyerp.com-20110708093022-qm22kull5wq1vvmi --- addons/account/__openerp__.py | 4 +- addons/account/edi_invoice_action.xml | 11 +- addons/stock/__init__.py | 3 +- addons/stock/__openerp__.py | 5 +- addons/stock/edi_stock_picking.py | 183 ++++++++++++++++++++++++++ 5 files changed, 195 insertions(+), 11 deletions(-) create mode 100644 addons/stock/edi_stock_picking.py diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index adc0e3ea7e2..d5818f0bf6d 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -122,14 +122,14 @@ 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.xml", ], 'demo_xml': [ 'account_demo.xml', 'project/project_demo.xml', 'project/analytic_account_demo.xml', 'demo/account_minimal.xml', - "edi_invoice_action.xml", + #"edi_invoice_action.xml", # 'account_unit_test.xml', ], 'test': [ diff --git a/addons/account/edi_invoice_action.xml b/addons/account/edi_invoice_action.xml index e5d7a3f5022..a7bb3d5edf7 100644 --- a/addons/account/edi_invoice_action.xml +++ b/addons/account/edi_invoice_action.xml @@ -3,7 +3,7 @@ - context.update({'token':self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)}) + context.update({'token':self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context),'invoice':object.number,'company':object.company_id.name,'currency':object.currency_id.name,'amount':object.amount_total,'date_due':object.date_due}) code ir.actions.server @@ -49,15 +49,14 @@ xyz - test ${object._context.get('token')} -${object.account_id.currency_mode} + Hello, -We just registered the invoice 'INV/001' for 121 EUR for your company 'ASUSTek'. +We just registered the invoice ${object.number} for ${object.amount}, ${object.currency} for your company ${object.company}. You can click on the following link to preview, print and pay this invoice: - http://URL_ON_WEB_CLIENT + http://localhost:8080/openerp/token? ${object._context.get('token')} -Please note that this invoice has to be paid before 12/04/2011. +Please note that this invoice has to be paid before ${object.date_due} Regards, mako diff --git a/addons/stock/__init__.py b/addons/stock/__init__.py index 78abee6d31d..4c4634babc1 100644 --- a/addons/stock/__init__.py +++ b/addons/stock/__init__.py @@ -24,5 +24,6 @@ import partner import product import report import wizard +import edi_stock_picking -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 1a33fd3012c..9e743b6ff0d 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -48,7 +48,7 @@ Thanks to the double entry management, the inventory controlling is powerful and "depends" : ["product", "account"], "category" : "Warehouse", "init_xml" : [], - "demo_xml" : ["stock_demo.xml"], + #"demo_xml" : ["stock_demo.xml"], "update_xml" : [ "security/stock_security.xml", "security/ir.model.access.csv", @@ -75,7 +75,8 @@ Thanks to the double entry management, the inventory controlling is powerful and "partner_view.xml", "report/report_stock_move_view.xml", "report/report_stock_view.xml", - "board_warehouse_view.xml" + "board_warehouse_view.xml", + "test/edi_stock_picking.yml", ], 'test': ['test/stock_test.yml', 'test/stock_report.yml', diff --git a/addons/stock/edi_stock_picking.py b/addons/stock/edi_stock_picking.py new file mode 100644 index 00000000000..d74a3ef5665 --- /dev/null +++ b/addons/stock/edi_stock_picking.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +from osv import fields, osv, orm +from base.ir import ir_edi +from tools.translate import _ + +class stock_picking(osv.osv, ir_edi.edi): + _inherit = 'stock.picking' + + def edi_export(self, cr, uid, records, edi_struct=None, context=None): + """Exports a supplier or customer invoice""" + edi_struct = { + + 'origin': True, + 'type': True, + 'stock_journal_id': True, + 'move_type': True, + 'date': True, + 'date_done': True, + 'move_lines': { + 'name': True, + 'date': True, + 'date_expected': True, + 'product_id': True, + 'product_qty': True, + 'product_uom': True, + 'location_id': True, + 'location_dest_id': True, + 'company_id': True, + }, + 'invoice_state': True, + 'address_id': True, + 'company_id': True, + } + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + company_address_dict = { + 'street': True, + 'street2': True, + 'zip': True, + 'city': True, + 'state_id': True, + 'country_id': True, + 'email': True, + 'phone': True, + + } + edi_doc_list = [] + for picking in records: + # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. + edi_doc = super(stock_picking,self).edi_export(cr, uid, [picking], edi_struct, context) + if not edi_doc: + continue + edi_doc = edi_doc[0] + + # Add company info and address + res = partner_pool.address_get(cr, uid, [picking.company_id.partner_id.id], ['contact', 'picking']) + contact_addr_id = res['contact'] + invoice_addr_id = res['picking'] + + address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) + edi_company_address_dict = {} + for key, value in company_address_dict.items(): + if not value: + continue + address_rec = getattr(address, key) + if not address_rec: + continue + if key.endswith('_id'): + address_rec = self.edi_m2o(cr, uid, address_rec, context=context) + edi_company_address_dict[key] = address_rec + + edi_doc.update({ + 'company_address': edi_company_address_dict, + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + edi_doc_list.append(edi_doc) + return edi_doc_list + + def edi_import(self, cr, uid, edi_document, context=None): + + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + model_data_pool = self.pool.get('ir.model.data') + product_pool = self.pool.get('product.product') + product_categ_pool = self.pool.get('product.category') + company_pool = self.pool.get('res.company') + country_pool = self.pool.get('res.country') + state_pool = self.pool.get('res.country.state') + account_journal_pool = self.pool.get('account.journal') + invoice_line_pool = self.pool.get('account.invoice.line') + account_pool = self.pool.get('account.account') + tax_id = [] + account_id = [] + partner_id = None + company_id = None + if context is None: + context = {} + + # import company as a new partner, if type==in then supplier=1, else customer=1 + # partner_id field is modified to point to the new partner + # company_address data used to add address to new partner + edi_company_address = edi_document['company_address'] + + company_name = edi_document['company_id'][1] + shipping_type = edi_document['type'] + state_id = edi_company_address.get('state_id', False) + state_name = state_id and state_id[1] + country_id = edi_company_address.get('country_id', False) + country_name = country_id and country_id[1] + + country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False + state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, + values={'country_id': country_id, 'code': state_name}, context=context) or False + address_value = { + 'street': edi_company_address.get('street', False), + 'street2': edi_company_address.get('street2', False), + 'zip': edi_company_address.get('zip', False), + 'city': edi_company_address.get('city', False), + 'state_id': state_id, + 'country_id': country_id, + 'email': edi_company_address.get('email', False), + 'phone': edi_company_address.get('phone', False), + + } + + + partner_value = {'name': company_name} + partner_id = partner_pool.search(cr, uid, [('name','=',company_name)]) + if len(partner_id): + partner_id = partner_pool.browse(cr, uid, partner_id[0], context=context) + address_id = partner_id.address[0].id + else: + partner_id = partner_pool.create(cr, uid, partner_value, context=context) + address_value.update({'partner_id': partner_id}) + address_id = partner_address_pool.create(cr, uid, address_value, context=context) + partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) + edi_document.update({'address_id': self.edi_m2o(cr, uid, partner_address, context=context)}) + + + + + # change type: out'<->'in for shipping + shipping_type = shipping_type.startswith('in') and shipping_type.replace('in','out') or shipping_type.replace('out','in') + edi_document['type'] = shipping_type + company_id = edi_document['company_id'] + #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",edi_document['move_lines'] + edi_document.update({'company_id': edi_document['move_lines'][0]['company_id']}) + edi_document['move_lines'][0].update({'company_id':company_id}) + + del edi_document['company_address'] + + + + return super(stock_picking,self).edi_import(cr, uid, edi_document, context=context) + +stock_picking() + +class stock_move(osv.osv, ir_edi.edi): + _inherit='stock.move' + +stock_move() + From 30b5f52c572e39f751227fc4301387b539c2a9b4 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Wed, 13 Jul 2011 15:49:07 +0530 Subject: [PATCH 013/316] [IMP] account: add some fields in EDI Dict of account.invoice which are display in Web EDI Interface bzr revid: hmo@tinyerp.com-20110713101907-oo7le07rtkwzpsdu --- addons/account/edi_invoice.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index f8f615b40fc..7c69b52b879 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -35,6 +35,10 @@ 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, 'date_invoice': True, 'date_due': True, 'partner_id': True, @@ -47,6 +51,7 @@ class account_invoice(osv.osv, ir_edi.edi): 'uos_id': True, 'product_id': True, 'price_unit': True, + 'price_subtotal': True, 'quantity': True, 'discount': True, 'note': True, From e087243c241382e59cae48a87289fa00f501415c Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 14 Jul 2011 16:27:16 +0530 Subject: [PATCH 014/316] [REVIEW] account: rename file name of edi_invoice_action_data bzr revid: hmo@tinyerp.com-20110714105716-xn54phkryzjuc94e --- addons/account/__openerp__.py | 3 +-- .../{edi_invoice_action.xml => edi_invoice_action_data.xml} | 0 addons/stock/__init__.py | 1 - addons/stock/__openerp__.py | 3 +-- 4 files changed, 2 insertions(+), 5 deletions(-) rename addons/account/{edi_invoice_action.xml => edi_invoice_action_data.xml} (100%) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index d5818f0bf6d..a0796fcf6b8 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -122,14 +122,13 @@ 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.xml", + "edi_invoice_action_data.xml", ], 'demo_xml': [ 'account_demo.xml', 'project/project_demo.xml', 'project/analytic_account_demo.xml', 'demo/account_minimal.xml', - #"edi_invoice_action.xml", # 'account_unit_test.xml', ], 'test': [ diff --git a/addons/account/edi_invoice_action.xml b/addons/account/edi_invoice_action_data.xml similarity index 100% rename from addons/account/edi_invoice_action.xml rename to addons/account/edi_invoice_action_data.xml diff --git a/addons/stock/__init__.py b/addons/stock/__init__.py index 4c4634babc1..0a241209593 100644 --- a/addons/stock/__init__.py +++ b/addons/stock/__init__.py @@ -24,6 +24,5 @@ import partner import product import report import wizard -import edi_stock_picking # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py index 9e743b6ff0d..f4facc9c4f7 100644 --- a/addons/stock/__openerp__.py +++ b/addons/stock/__openerp__.py @@ -48,7 +48,7 @@ Thanks to the double entry management, the inventory controlling is powerful and "depends" : ["product", "account"], "category" : "Warehouse", "init_xml" : [], - #"demo_xml" : ["stock_demo.xml"], + "demo_xml" : ["stock_demo.xml"], "update_xml" : [ "security/stock_security.xml", "security/ir.model.access.csv", @@ -76,7 +76,6 @@ Thanks to the double entry management, the inventory controlling is powerful and "report/report_stock_move_view.xml", "report/report_stock_view.xml", "board_warehouse_view.xml", - "test/edi_stock_picking.yml", ], 'test': ['test/stock_test.yml', 'test/stock_report.yml', From ced29b87a0a05c41ec8f505139b97babe636e711 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 14 Jul 2011 16:32:55 +0530 Subject: [PATCH 015/316] [IMP] account: add dependancy of email_template module bzr revid: hmo@tinyerp.com-20110714110255-65ny7ujd5arcxz37 --- addons/account/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index a0796fcf6b8..6e6d1b79f99 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -52,7 +52,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" : ["product", "analytic", "process","board"], + "depends" : ["product", "analytic", "process","board", "email_template"], 'update_xml': [ 'security/account_security.xml', 'security/ir.model.access.csv', From 7e77228d291cddc80b52483d84931b2423a8c739 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Jul 2011 13:14:42 +0530 Subject: [PATCH 016/316] [REVIEW] account: correct server action and email template data and add default email template bzr revid: hmo@tinyerp.com-20110715074442-w9u3y0wv3s5omoll --- addons/account/edi_invoice_action_data.xml | 63 +++++++------------ .../email_template_scheduler_data.xml | 8 +++ 2 files changed, 30 insertions(+), 41 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index a7bb3d5edf7..75e814216e7 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -2,69 +2,50 @@ - - context.update({'token':self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context),'invoice':object.number,'company':object.company_id.name,'currency':object.currency_id.name,'amount':object.amount_total,'date_due':object.date_due}) + + context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +if object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, + uid, + self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')[1], + [object.id], + context=context) code ir.actions.server True - invoice - - - - - - hello - invoice created - email - ir.actions.server - han@tinyerp.com - - True - invoice_send - - - - - - other - ir.actions.server - - - True - Multi_action + EDI Document - Invoice + - + + - - - invoice - xyz - + + + ${object.company_id.name} - Invoice ${object.number} + ${object.address_invoice_id.email} - xyz + True -Hello, +Hello ${object.partner_id.name}, -We just registered the invoice ${object.number} for ${object.amount}, ${object.currency} for your company ${object.company}. +We just registered the invoice ${object.number} for ${object.amount_total} ${object.currency_id.name} for your company ${object.company_id.name}. You can click on the following link to preview, print and pay this invoice: - http://localhost:8080/openerp/token? ${object._context.get('token')} + + ${object._context.get('edi_web_url_view')} Please note that this invoice has to be paid before ${object.date_due} Regards, mako - english - xyz - Invoice + Mail Template of Invoice For EDI Document account.invoice - xyz + ${object.user_id.email or ''} diff --git a/addons/email_template/email_template_scheduler_data.xml b/addons/email_template/email_template_scheduler_data.xml index 45a9be04ac7..910aa8572e6 100644 --- a/addons/email_template/email_template_scheduler_data.xml +++ b/addons/email_template/email_template_scheduler_data.xml @@ -1,6 +1,14 @@ + + + Default EMail Template Account + test@localhost + draft + + + Email Template scheduler From 17e25609ed72ebce2ce7edf33ae54d39a4f5efec Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Jul 2011 14:02:49 +0530 Subject: [PATCH 017/316] [REM] stock: EDI feature will be included later bzr revid: hmo@tinyerp.com-20110715083249-02cutonhjovv2z2k --- addons/stock/edi_stock_picking.py | 183 ------------------------------ 1 file changed, 183 deletions(-) delete mode 100644 addons/stock/edi_stock_picking.py diff --git a/addons/stock/edi_stock_picking.py b/addons/stock/edi_stock_picking.py deleted file mode 100644 index d74a3ef5665..00000000000 --- a/addons/stock/edi_stock_picking.py +++ /dev/null @@ -1,183 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2009 Tiny SPRL (). -# -# 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 . -# -############################################################################## - -from osv import fields, osv, orm -from base.ir import ir_edi -from tools.translate import _ - -class stock_picking(osv.osv, ir_edi.edi): - _inherit = 'stock.picking' - - def edi_export(self, cr, uid, records, edi_struct=None, context=None): - """Exports a supplier or customer invoice""" - edi_struct = { - - 'origin': True, - 'type': True, - 'stock_journal_id': True, - 'move_type': True, - 'date': True, - 'date_done': True, - 'move_lines': { - 'name': True, - 'date': True, - 'date_expected': True, - 'product_id': True, - 'product_qty': True, - 'product_uom': True, - 'location_id': True, - 'location_dest_id': True, - 'company_id': True, - }, - 'invoice_state': True, - 'address_id': True, - 'company_id': True, - } - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - company_address_dict = { - 'street': True, - 'street2': True, - 'zip': True, - 'city': True, - 'state_id': True, - 'country_id': True, - 'email': True, - 'phone': True, - - } - edi_doc_list = [] - for picking in records: - # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. - edi_doc = super(stock_picking,self).edi_export(cr, uid, [picking], edi_struct, context) - if not edi_doc: - continue - edi_doc = edi_doc[0] - - # Add company info and address - res = partner_pool.address_get(cr, uid, [picking.company_id.partner_id.id], ['contact', 'picking']) - contact_addr_id = res['contact'] - invoice_addr_id = res['picking'] - - address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) - edi_company_address_dict = {} - for key, value in company_address_dict.items(): - if not value: - continue - address_rec = getattr(address, key) - if not address_rec: - continue - if key.endswith('_id'): - address_rec = self.edi_m2o(cr, uid, address_rec, context=context) - edi_company_address_dict[key] = address_rec - - edi_doc.update({ - 'company_address': edi_company_address_dict, - #'company_logo': inv_comp.logo,#TODO - #'paid': inv_comp.paid, #TODO - }) - edi_doc_list.append(edi_doc) - return edi_doc_list - - def edi_import(self, cr, uid, edi_document, context=None): - - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - model_data_pool = self.pool.get('ir.model.data') - product_pool = self.pool.get('product.product') - product_categ_pool = self.pool.get('product.category') - company_pool = self.pool.get('res.company') - country_pool = self.pool.get('res.country') - state_pool = self.pool.get('res.country.state') - account_journal_pool = self.pool.get('account.journal') - invoice_line_pool = self.pool.get('account.invoice.line') - account_pool = self.pool.get('account.account') - tax_id = [] - account_id = [] - partner_id = None - company_id = None - if context is None: - context = {} - - # import company as a new partner, if type==in then supplier=1, else customer=1 - # partner_id field is modified to point to the new partner - # company_address data used to add address to new partner - edi_company_address = edi_document['company_address'] - - company_name = edi_document['company_id'][1] - shipping_type = edi_document['type'] - state_id = edi_company_address.get('state_id', False) - state_name = state_id and state_id[1] - country_id = edi_company_address.get('country_id', False) - country_name = country_id and country_id[1] - - country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False - state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, - values={'country_id': country_id, 'code': state_name}, context=context) or False - address_value = { - 'street': edi_company_address.get('street', False), - 'street2': edi_company_address.get('street2', False), - 'zip': edi_company_address.get('zip', False), - 'city': edi_company_address.get('city', False), - 'state_id': state_id, - 'country_id': country_id, - 'email': edi_company_address.get('email', False), - 'phone': edi_company_address.get('phone', False), - - } - - - partner_value = {'name': company_name} - partner_id = partner_pool.search(cr, uid, [('name','=',company_name)]) - if len(partner_id): - partner_id = partner_pool.browse(cr, uid, partner_id[0], context=context) - address_id = partner_id.address[0].id - else: - partner_id = partner_pool.create(cr, uid, partner_value, context=context) - address_value.update({'partner_id': partner_id}) - address_id = partner_address_pool.create(cr, uid, address_value, context=context) - partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) - edi_document.update({'address_id': self.edi_m2o(cr, uid, partner_address, context=context)}) - - - - - # change type: out'<->'in for shipping - shipping_type = shipping_type.startswith('in') and shipping_type.replace('in','out') or shipping_type.replace('out','in') - edi_document['type'] = shipping_type - company_id = edi_document['company_id'] - #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",edi_document['move_lines'] - edi_document.update({'company_id': edi_document['move_lines'][0]['company_id']}) - edi_document['move_lines'][0].update({'company_id':company_id}) - - del edi_document['company_address'] - - - - return super(stock_picking,self).edi_import(cr, uid, edi_document, context=context) - -stock_picking() - -class stock_move(osv.osv, ir_edi.edi): - _inherit='stock.move' - -stock_move() - From e1a12a3c434007bdc55f7854a867c039854f2294 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Jul 2011 14:13:43 +0530 Subject: [PATCH 018/316] [FIX] account.edi_invoice: export value of reconciled field bzr revid: hmo@tinyerp.com-20110715084343-135d1hc6057j1sb4 --- addons/account/edi_invoice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 7c69b52b879..786fbb0b018 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -39,6 +39,7 @@ class account_invoice(osv.osv, ir_edi.edi): 'amount_untaxed': True, 'amount_tax': True, 'amount_total': True, + 'reconciled': True, 'date_invoice': True, 'date_due': True, 'partner_id': True, From a5d8abd4ada1e9f436755b66face4ba20e3b597f Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Jul 2011 16:29:13 +0530 Subject: [PATCH 019/316] [FIX] account.edi_invoice: import correct address of partner bzr revid: hmo@tinyerp.com-20110715105913-kzcidgprxczq3mao --- addons/account/edi_invoice.py | 3 +++ addons/account/edi_invoice_action_data.xml | 7 +++---- addons/email_template/email_template_scheduler_data.xml | 8 -------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 786fbb0b018..22d1c793f22 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -196,6 +196,9 @@ class account_invoice(osv.osv, ir_edi.edi): partner = partner_pool.browse(cr, uid, partner_id, context=context) edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) + partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) + edi_document['address_invoice_id'] = self.edi_m2o(cr, uid, partner_address, context=context) + # change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund' invoice_type = invoice_type.startswith('in_') and invoice_type.replace('in_','out_') or invoice_type.replace('out_','in_') edi_document['type'] = invoice_type diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index 75e814216e7..af778e2abe0 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -26,13 +26,11 @@ if object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, - ${object.company_id.name} - Invoice ${object.number} ${object.address_invoice_id.email} True - -Hello ${object.partner_id.name}, + Hello ${object.partner_id.name}, We just registered the invoice ${object.number} for ${object.amount_total} ${object.currency_id.name} for your company ${object.company_id.name}. You can click on the following link to preview, print and pay this invoice: @@ -41,7 +39,8 @@ You can click on the following link to preview, print and pay this invoice: Please note that this invoice has to be paid before ${object.date_due} -Regards, +Regards, + mako Mail Template of Invoice For EDI Document account.invoice diff --git a/addons/email_template/email_template_scheduler_data.xml b/addons/email_template/email_template_scheduler_data.xml index 910aa8572e6..45a9be04ac7 100644 --- a/addons/email_template/email_template_scheduler_data.xml +++ b/addons/email_template/email_template_scheduler_data.xml @@ -1,14 +1,6 @@ - - - Default EMail Template Account - test@localhost - draft - - - Email Template scheduler From 1e27a50175223eb70cfbe30756125e57119a2595 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 15 Jul 2011 17:12:12 +0530 Subject: [PATCH 020/316] [FIX] account.edi_invoice: correct email template bzr revid: hmo@tinyerp.com-20110715114212-bh2kv0ev03dpdm6d --- addons/account/edi_invoice_action_data.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index af778e2abe0..4cf3de86489 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -30,14 +30,14 @@ if object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, ${object.address_invoice_id.email} True - Hello ${object.partner_id.name}, + Hello ${object.address_invoice_id.name}, -We just registered the invoice ${object.number} for ${object.amount_total} ${object.currency_id.name} for your company ${object.company_id.name}. +We just registered the invoice ${object.number} for ${object.amount_total} ${object.currency_id.name} for your company ${object.partner_id.name}. You can click on the following link to preview, print and pay this invoice: ${object._context.get('edi_web_url_view')} -Please note that this invoice has to be paid before ${object.date_due} +Please note that this invoice has to be paid before ${object.date_due or ''} Regards, From 2357eb562e96c563793cfd4b1c34f9bfe87520dc Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 18 Aug 2011 17:36:04 +0200 Subject: [PATCH 021/316] [FIX] document_ftp: avoid calling res.users.read() with too few arguments (it's broken, pending fix) bzr revid: odo@openerp.com-20110818153604-gefze43wp1u63j02 --- addons/document_ftp/test_easyftp.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/document_ftp/test_easyftp.py b/addons/document_ftp/test_easyftp.py index ac2cd722478..74890b1a333 100644 --- a/addons/document_ftp/test_easyftp.py +++ b/addons/document_ftp/test_easyftp.py @@ -36,13 +36,13 @@ def get_plain_ftp(timeout=10.0): def get_ftp_login(cr, uid, ormobj): ftp = get_plain_ftp() - user = ormobj.pool.get('res.users').read(cr, uid, uid) - passwd = user.get('password','') + user = ormobj.pool.get('res.users').browse(cr, uid, uid) + passwd = user.password or '' if passwd.startswith("$1$"): - # md5 by base crypt. We cannot decode, wild guess + # md5 by base crypt. We cannot decode, wild guess # that passwd = login - passwd = user.get('login', '') - ftp.login(user.get('login',''), passwd) + passwd = user.login + ftp.login(user.login, passwd) ftp.cwd("/" + cr.dbname) return ftp From b46c2554467b719fdef76c3a14a79878919f10bb Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 26 Aug 2011 17:55:19 +0530 Subject: [PATCH 022/316] [FIX] account: email template of account invoice bzr revid: hmo@tinyerp.com-20110826122519-3bk1phpg3jtw5mfn --- addons/account/edi_invoice_action_data.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index 95633aea21b..dc6cca4fade 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -3,7 +3,7 @@ - context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) + context.update({'edi_web_invoice_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')[1], @@ -34,13 +34,13 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( <p> Hello ${object.address_invoice_id.name and ' ' or ''},</p> <p> You can click on the following link to preview, print and pay invoice: - <a href="${object._context.get('edi_web_url_view')}">${object._context.get('edi_web_url_view')}</a> + <a href="${object._context.get('edi_web_invoice_url_view')}">$${object._context.get('edi_web_invoice_url_view')} </a> </p> <p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Invoice number: <strong>${object.number}</strong><br /> Invoice amount: <strong>${object.amount_total} ${object.currency_id.name}</strong><br /> Invoice date: ${object.date_invoice or 'n/a'}<br /> Order reference: ${object.origin or 'n/a'}<br /> Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a></p> -${object.company_id.paypal_account and '<p>It is possible to pay with Paypal: <br/> <a href=/"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business='+object.company_id.paypal_account+'&item_name=OpenERP%20Invoice%20'+object.number and object.number.replace('/','%2f') or ''+'&invoice='+object.number and object.number.replace('/','%2f') or ''+'&amount='+object.amount_total+'&currency_code='+object.currency_id.name+'&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_'+object.currency_id.name+'/"><img src=/"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif/" style=/"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;/"/></a> </p>'} +${object.company_id.paypal_account and "<p>It is possible to pay with Paypal: <br/> <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s\"><img src=\"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif\" style=\"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;\"/></a> </p>"%(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) or ''} <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a></div> <div> </div> </div> </div> <p> </p> @@ -49,15 +49,15 @@ Hello ${object.address_invoice_id.name and ' ' or ''}, You can click on the following link to preview, print and pay invoice: - ${object._context.get('edi_web_url_view')} + ${object._context.get('edi_web_invoice_url_view') or 'n/a'} Invoice Number: *${object.number}* Amount: *${object.amount_total} ${object.currency_id.name}* Invoice date: ${object.date_invoice or 'n/a'} Order reference: ${object.origin or 'n/a'} -Your contact: ${object.user_id.name} <${object.user_id.user_email or ''}> +Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} -${object.company_id.paypal_account and 'It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business='+object.company_id.paypal_account+'&item_name=OpenERP%20Invoice%20'+object.number and object.number.replace('/','%2f') or ''+'&invoice='+object.number and object.number.replace('/','%2f') or ''+'&amount='+object.amount_total+'&currency_code='+object.currency_id.name+'&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_'+object.currency_id.name} +${object.company_id.paypal_account and "It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&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) or ''} If you have any question, do not hesitate to reply directly to this e-mail. @@ -65,7 +65,7 @@ Thank you for choosing our service! -- ${object.company_id.name} -Contact: ${object.user_id.name} <${object.user_id.user_email or ''}> +Contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} mako Mail Template of Invoice For EDI Document From 333b5aa3e2bdcfdae54f2fcc9e9be3d0574dbd85 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Fri, 26 Aug 2011 18:39:29 +0530 Subject: [PATCH 023/316] [IMP] edi sale order with email template bzr revid: han@tinyerp.com-20110826130929-q0n8o9gdy8a6ssf0 --- addons/sale/__init__.py | 2 +- addons/sale/__openerp__.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index 3c7af56e808..6361fea3a0b 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -29,5 +29,5 @@ import sale_installer import wizard import report import company - +import edi_sale_order # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index c983edc881e..4dccadc34e2 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -85,6 +85,7 @@ Dashboard for Sales Manager that includes: 'stock_view.xml', 'board_sale_view.xml', 'process/sale_process.xml', + 'edi_sale_order_data.xml', ], 'demo_xml': ['sale_demo.xml'], 'test': [ From 1ed41c0578aa05ef67709a2d9520a8eae3b25a3c Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Fri, 26 Aug 2011 18:40:37 +0530 Subject: [PATCH 024/316] [imp] edi sale order bzr revid: han@tinyerp.com-20110826131037-fr63ylzjd8ev1l5j --- addons/sale/edi_sale_order.py | 195 ++++++++++++++++++++++++++++ addons/sale/edi_sale_order_data.xml | 51 ++++++++ 2 files changed, 246 insertions(+) create mode 100644 addons/sale/edi_sale_order.py create mode 100644 addons/sale/edi_sale_order_data.xml diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py new file mode 100644 index 00000000000..266727c0ae5 --- /dev/null +++ b/addons/sale/edi_sale_order.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +from osv import fields, osv, orm +from base.ir import ir_edi +from tools.translate import _ +from datetime import date +class sale_order(osv.osv, ir_edi.edi): + _inherit = 'sale.order' + + def edi_export(self, cr, uid, records, edi_struct=None, context=None): + """Exports a Sale order""" + edi_struct = { + 'name': True, + 'shop_id': True, + 'origin': True, + 'amount_total': True, + 'date_order': True, + 'create_date': True, + 'date_confirm': True, + 'partner_id': True, + 'partner_invoice_id': True, + 'partner_order_id': True, + 'partner_shipping_id': True, + 'incoterm': True, + 'picking_policy': True, + 'order_policy': True, + 'pricelist_id': True, + 'project_id': True, + 'invoice_quantity': True, + 'order_line': { + 'name': True, + 'sequence': True, + 'product_id': True, + 'invoiced': True, + 'procurement_id': True, + 'price_unit': True, + 'type': True, + 'price_subtotal': True, + 'tax_id': True, + 'address_allotment_id': True, + 'product_uom': True, + 'product_uom_qty': True, + 'product_uos': True, + 'notes': True, + + }, + 'shipped': True, + } + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + company_address_dict = { + 'street': True, + 'street2': True, + 'zip': True, + 'city': True, + 'state_id': True, + 'country_id': True, + 'email': True, + 'phone': True, + + } + edi_doc_list = [] + for order in records: + # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. + edi_doc = super(sale_order,self).edi_export(cr, uid, [order], edi_struct, context) + if not edi_doc: + continue + edi_doc = edi_doc[0] + + # Add company info and address + res = partner_pool.address_get(cr, uid, [order.shop_id.company_id.partner_id.id], ['contact', 'order']) + contact_addr_id = res['contact'] + invoice_addr_id = res['order'] + + address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) + edi_company_address_dict = {} + for key, value in company_address_dict.items(): + if not value: + continue + address_rec = getattr(address, key) + if not address_rec: + continue + if key.endswith('_id'): + address_rec = self.edi_m2o(cr, uid, address_rec, context=context) + + edi_company_address_dict[key] = address_rec + + edi_doc.update({ + 'company_address': edi_company_address_dict, + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + edi_doc_list.append(edi_doc) + return edi_doc_list + + def edi_import(self, cr, uid, edi_document, context=None): + + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + model_data_pool = self.pool.get('ir.model.data') + product_pool = self.pool.get('product.product') + product_categ_pool = self.pool.get('product.category') + company_pool = self.pool.get('res.company') + country_pool = self.pool.get('res.country') + state_pool = self.pool.get('res.country.state') + + tax_id = [] + account_id = [] + partner_id = None + company_id = None + if context is None: + context = {} + + # import company as a new partner, if type==in then supplier=1, else customer=1 + # partner_id field is modified to point to the new partner + # company_address data used to add address to new partner + edi_company_address = edi_document['company_address'] + edi_partner_id = edi_document['partner_id'] + company_name = edi_document['company_id'][1] + state_id = edi_company_address.get('state_id', False) + state_name = state_id and state_id[1] + country_id = edi_company_address.get('country_id', False) + country_name = country_id and country_id[1] + + country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False + state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, + values={'country_id': country_id, 'code': state_name}, context=context) or False + address_value = { + 'street': edi_company_address.get('street', False), + 'street2': edi_company_address.get('street2', False), + 'zip': edi_company_address.get('zip', False), + 'city': edi_company_address.get('city', False), + 'state_id': state_id, + 'country_id': country_id, + 'email': edi_company_address.get('email', False), + 'phone': edi_company_address.get('phone', False), + + } + + partner_value = {'name': company_name} + partner_value.update({'customer': True, 'supplier': False}) + + partner_id = partner_pool.create(cr, uid, partner_value, context=context) + address_value.update({'partner_id': partner_id}) + address_id = partner_address_pool.create(cr, uid, address_value, context=context) + partner_address = partner_address_pool.browse(cr, uid, [address_id], context=context) + partner_address_id = self.edi_o2m(cr, uid, partner_address, context=context) + partner = partner_pool.browse(cr, uid, partner_id, context=context) + edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) + edi_document.update({ + 'partner_invoice_id': partner_address_id, + 'partner_order_id': partner_address_id, + 'partner_shipping_id': partner_address_id, + #'product_uom_qty': edi_document['order_line'][0]['product_qty'], + 'delay': 10, + }) + # all fields are converted for sale order import so unnecessary fields are deleted + del edi_document['order_line'][0]['date_planned'] + del edi_document['order_line'][0]['product_qty'] + del edi_document['date_approve'] + del edi_document['validator'] + + del edi_document['location_id'] + del edi_document['partner_address_id'] + del edi_document['company_address'] + del edi_document['company_id'] + del edi_document['warehouse_id'] + return super(sale_order,self).edi_import(cr, uid, edi_document, context=context) + +sale_order() + +class sale_order_line(osv.osv, ir_edi.edi): + _inherit='sale.order.line' + +sale_order_line() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml new file mode 100644 index 00000000000..70b6adae397 --- /dev/null +++ b/addons/sale/edi_sale_order_data.xml @@ -0,0 +1,51 @@ + + + + + + context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, + uid, + self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], + [object.id], + context=context) + + code + ir.actions.server + + True + EDI Document - Sale Order + + + + + + + + + + + + ${object.company_id.name} - Sale Order ${object.name} + ${object.partner_invoice_id.email} + + True + +Hello ${object.partner_invoice_id.name}, + +We just registered the sale order ${object.name} for ${object.amount_total} for your company ${object.partner_id.name}. +You can click on the following link to preview. + + ${object._context.get('edi_web_url_view')} + + confirmed on ${object.date_confirm} + +Regards, + + mako + Mail Template of Sale Order For EDI Document + sale.order + ${object.user_id.email or ''} + + + From 39b40d789a2d23f985923447a8ce3d9f55b8c6f8 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 29 Aug 2011 13:09:56 +0530 Subject: [PATCH 025/316] [IMP] account: email template of account invoice bzr revid: hmo@tinyerp.com-20110829073956-vabkylrsvnklb8hw --- addons/account/edi_invoice_action_data.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index dc6cca4fade..fb89e585195 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -33,8 +33,8 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( <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); "> <p> Hello ${object.address_invoice_id.name and ' ' or ''},</p> -<p> You can click on the following link to preview, print and pay invoice: - <a href="${object._context.get('edi_web_invoice_url_view')}">$${object._context.get('edi_web_invoice_url_view')} </a> +<p> You can click on the following link to preview, print and pay invoice: <br/> + <a href="${object._context.get('edi_web_invoice_url_view')}">${object._context.get('edi_web_invoice_url_view')} </a> </p> From 37263ec7accdb62e33f686c566ac4db81bdf46c3 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Mon, 29 Aug 2011 15:51:27 +0530 Subject: [PATCH 026/316] [merge] edi sale order with yml bzr revid: han@tinyerp.com-20110829102127-nkr1muz2e1jsu6xh --- addons/purchase/__init__.py | 1 + addons/sale/__openerp__.py | 1 + addons/sale/edi_sale_order.py | 4 +-- addons/sale/test/edi_sale_order.yml | 51 +++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 addons/sale/test/edi_sale_order.yml diff --git a/addons/purchase/__init__.py b/addons/purchase/__init__.py index 301e32ebca9..87e13840e0d 100644 --- a/addons/purchase/__init__.py +++ b/addons/purchase/__init__.py @@ -26,6 +26,7 @@ import wizard import report import stock import company +import edi_purchase_order # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 4dccadc34e2..0e3ec9ed075 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -100,6 +100,7 @@ Dashboard for Sales Manager that includes: 'test/invoice_on_ordered_qty.yml', 'test/invoice_on_shipped_qty.yml', 'test/sale_report.yml', + 'test/edi_sale_order.yml', ], 'installable': True, 'active': False, diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py index 266727c0ae5..ea1a56b1ed4 100644 --- a/addons/sale/edi_sale_order.py +++ b/addons/sale/edi_sale_order.py @@ -38,8 +38,6 @@ class sale_order(osv.osv, ir_edi.edi): 'date_confirm': True, 'partner_id': True, 'partner_invoice_id': True, - 'partner_order_id': True, - 'partner_shipping_id': True, 'incoterm': True, 'picking_policy': True, 'order_policy': True, @@ -163,7 +161,7 @@ class sale_order(osv.osv, ir_edi.edi): address_value.update({'partner_id': partner_id}) address_id = partner_address_pool.create(cr, uid, address_value, context=context) partner_address = partner_address_pool.browse(cr, uid, [address_id], context=context) - partner_address_id = self.edi_o2m(cr, uid, partner_address, context=context) + partner_address_id = self.edi_o2m(cr, uid, [partner_address], context=context) partner = partner_pool.browse(cr, uid, partner_id, context=context) edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) edi_document.update({ diff --git a/addons/sale/test/edi_sale_order.yml b/addons/sale/test/edi_sale_order.yml new file mode 100644 index 00000000000..dba200f4cfa --- /dev/null +++ b/addons/sale/test/edi_sale_order.yml @@ -0,0 +1,51 @@ +- + I create a partner which is a my customer +- + !record {model: res.partner, id: res_partner_test22}: + name: Junjun wala + supplier: False + customer: True + opt_out: False +- + I create one Sale Order +- + !record {model: sale.order, id: sale_order_test}: + partner_id: res_partner_test22 + partner_invoice_id: base.res_partner_address_11 + partner_order_id: base.res_partner_address_11 + partner_shipping_id: base.res_partner_address_11 + pricelist_id: 1 + order_line: + - product_id: product.product_product_pc1 + product_uom_qty: 1.0 + product_uom: 1 + price_unit: 150.0 + name: 'basic pc' +- + I Open the sale order +- + !python {model: sale.order}: | + + orders = self.browse(cr, uid, ref("sale_order_test")) + import netsvc + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, 'sale.order',orders.id,'order_confirm', cr) + +- + I Tesing of EDI functionality. First I export Sale Order from my company than import that Order into customer company +- + !python {model: ir.edi.document}: | + import json + invoice_pool = self.pool.get('sale.order') + orders = invoice_pool.browse(cr, uid, ref("sale_order_test")) + + tokens = self.export_edi(cr, uid, [orders]) + assert tokens, 'Token is not generated' + document = self.get_document(cr, uid, tokens[0]) + document = json.loads(document) + document[0]["__model"] = "purchase.order" + document = json.dumps(document) + a = self.import_edi(cr, uid, edi_document = document) + assert a, 'Invoice is not imported' + + From 7d33fcfa66a383b963e7c46fbd768bb07444476a Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Mon, 29 Aug 2011 16:13:27 +0530 Subject: [PATCH 027/316] [IMP] develop a edi purchase order import and export bzr revid: aar@tinyerp.com-20110829104327-tikju8eodq6q6901 --- addons/purchase/__init__.py | 2 +- addons/purchase/__openerp__.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/purchase/__init__.py b/addons/purchase/__init__.py index 301e32ebca9..ddd572d8e81 100644 --- a/addons/purchase/__init__.py +++ b/addons/purchase/__init__.py @@ -26,6 +26,6 @@ import wizard import report import stock import company - +import edi_purchase_order # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/__openerp__.py b/addons/purchase/__openerp__.py index 975754dd5fe..f360d881cf3 100644 --- a/addons/purchase/__openerp__.py +++ b/addons/purchase/__openerp__.py @@ -58,6 +58,7 @@ Dashboard for purchase management that includes: 'process/purchase_process.xml', 'report/purchase_report_view.xml', 'board_purchase_view.xml', + 'edi_purchase_order_data.xml', ], 'test': [ 'test/purchase_from_order.yml', @@ -66,6 +67,7 @@ Dashboard for purchase management that includes: 'purchase_unit_test.xml', 'test/procurement_buy.yml', 'test/purchase_report.yml', + #'test/edi_purchase_order.yml', ], 'demo': ['purchase_demo.xml'], 'installable': True, From d6b7e8abb72acd533e511ef0127371133ab5aee7 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Mon, 29 Aug 2011 16:14:21 +0530 Subject: [PATCH 028/316] [IMP] develop a edi purchase order import and export bzr revid: aar@tinyerp.com-20110829104421-6562nvcyulzl4o84 --- addons/purchase/edi_purchase_order.py | 190 ++++++++++++++++++++ addons/purchase/edi_purchase_order_data.xml | 51 ++++++ addons/purchase/test/edi_purchase_order.yml | 31 ++++ 3 files changed, 272 insertions(+) create mode 100644 addons/purchase/edi_purchase_order.py create mode 100644 addons/purchase/edi_purchase_order_data.xml create mode 100644 addons/purchase/test/edi_purchase_order.yml diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py new file mode 100644 index 00000000000..1ea43afbb09 --- /dev/null +++ b/addons/purchase/edi_purchase_order.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +from osv import fields, osv, orm +from base.ir import ir_edi +from tools.translate import _ +from datetime import date + +class purchase_order(osv.osv, ir_edi.edi): + _inherit = 'purchase.order' + + def edi_export(self, cr, uid, records, edi_struct=None, context=None): + """Exports a supplier or customer invoice""" + edi_struct = { + 'name': True, + 'origin': True, + 'date_order': True, + 'date_approve': True, + 'partner_id': True, + 'partner_address_id': True, + 'dest_address_id': True, + 'warehouse_id': True, + 'location_id': True, + 'pricelist_id': True, + 'validator' : True, + 'order_line': { + 'name': True, + 'product_qty': True, + 'date_planned': True, + 'taxes_id': True, + 'product_uom': True, + 'product_id': True, + 'move_dest_id': True, + 'price_unit': True, + 'order_id': True, + 'invoiced': True, + 'price_subtotal': True, + }, + 'invoice_ids': True, + 'shipped': True, + 'company_id': True, + } + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + company_address_dict = { + 'street': True, + 'street2': True, + 'zip': True, + 'city': True, + 'state_id': True, + 'country_id': True, + 'email': True, + 'phone': True, + + } + edi_doc_list = [] + for order in records: + # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. + edi_doc = super(purchase_order,self).edi_export(cr, uid, [order], edi_struct, context) + if not edi_doc: + continue + edi_doc = edi_doc[0] + + # Add company info and address + res = partner_pool.address_get(cr, uid, [order.company_id.partner_id.id], ['contact', 'order']) + contact_addr_id = res['contact'] + invoice_addr_id = res['order'] + + address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) + edi_company_address_dict = {} + for key, value in company_address_dict.items(): + if not value: + continue + address_rec = getattr(address, key) + if not address_rec: + continue + if key.endswith('_id'): + address_rec = self.edi_m2o(cr, uid, address_rec, context=context) + edi_company_address_dict[key] = address_rec + + edi_doc.update({ + 'company_address': edi_company_address_dict, + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + edi_doc_list.append(edi_doc) + return edi_doc_list + + def edi_import(self, cr, uid, edi_document, context=None): + + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + model_data_pool = self.pool.get('ir.model.data') + product_pool = self.pool.get('product.product') + product_categ_pool = self.pool.get('product.category') + company_pool = self.pool.get('res.company') + country_pool = self.pool.get('res.country') + state_pool = self.pool.get('res.country.state') + account_journal_pool = self.pool.get('account.journal') + invoice_line_pool = self.pool.get('account.invoice.line') + account_pool = self.pool.get('account.account') + stock = self.pool.get('stock.location') + + tax_id = [] + account_id = [] + partner_id = None + company_id = None + if context is None: + context = {} + + # import company as a new partner, if type==in then supplier=1, else customer=1 + # partner_id field is modified to point to the new partner + # company_address data used to add address to new partner + edi_company_address = edi_document['company_address'] + edi_partner_id = edi_document['partner_id'] + company_name = edi_document['shop_id'][1] + state_id = edi_company_address.get('state_id', False) + state_name = state_id and state_id[1] + country_id = edi_company_address.get('country_id', False) + country_name = country_id and country_id[1] + + country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False + state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, + values={'country_id': country_id, 'code': state_name}, context=context) or False + address_value = { + 'street': edi_company_address.get('street', False), + 'street2': edi_company_address.get('street2', False), + 'zip': edi_company_address.get('zip', False), + 'city': edi_company_address.get('city', False), + 'state_id': state_id, + 'country_id': country_id, + 'email': edi_company_address.get('email', False), + 'phone': edi_company_address.get('phone', False), + + } + partner_value = {'name': company_name} + partner_value.update({'customer': False, 'supplier': True}) + partner_id = partner_pool.create(cr, uid, partner_value, context=context) + address_value.update({'partner_id': partner_id}) + address_id = partner_address_pool.create(cr, uid, address_value, context=context) + partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) + edi_document.update({'partner_address_id':self.edi_m2o(cr, uid, partner_address, context=context)}) + partner = partner_pool.browse(cr, uid, partner_id, context=context) + edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) + location_id = stock.search(cr, uid,[('name','=','Stock')]) + location = stock.browse(cr, uid, location_id[0]) + edi_document.update({'dest_address_id': edi_document['partner_shipping_id'],'location_id': self.edi_m2o(cr, uid, location, context=context)}) + + for line in range(len(edi_document['order_line'])): + product_qty = edi_document['order_line'][line]['product_uom_qty'] + edi_document['order_line'][line].update({'product_qty': product_qty}) + + # all fields are converted for purchase order import so unnecessary fields are deleted + delete_key = ['sequence','procurement_id','product_uom_qty','company_address','shop_id','create_date','picking_policy','order_policy','partner_order_id','partner_shipping_id','invoice_quantity','partner_invoice_id','price_subtotal','date_confirm'] + for key in delete_key: + if edi_document.has_key(key): + del edi_document[key] + else: + for document in edi_document['order_line']: + if document.has_key(key): + del document[key] + + print edi_document + return super(purchase_order,self).edi_import(cr, uid, edi_document, context=context) + +purchase_order() + +class purchase_order_line(osv.osv, ir_edi.edi): + _inherit='purchase.order.line' + +purchase_order_line() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml new file mode 100644 index 00000000000..ab29119bed1 --- /dev/null +++ b/addons/purchase/edi_purchase_order_data.xml @@ -0,0 +1,51 @@ + + + + + + context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +self.pool.get('email.template').generate_mail(cr, + uid, + self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase')[1], + [object.id], + context=context) + + code + ir.actions.server + + True + EDI Document - Purchase Order + + + + + + + + + + + + ${object.company_id.name} - Purchase Order ${object.name} + ${object.partner_address_id.email} + + True + +Hello ${object.partner_address_id.name}, + +We just registered the purchase order ${object.name} for ${object.amount_total} for your company ${object.partner_id.name}. +You can click on the following link to preview. + + ${object._context.get('edi_web_url_view')} + + Confirmed on ${object.date_approve} + +Regards, + + mako + Mail Template of Purchase Order For EDI Document + purchase.order + + + + diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml new file mode 100644 index 00000000000..2901aeb5e9a --- /dev/null +++ b/addons/purchase/test/edi_purchase_order.yml @@ -0,0 +1,31 @@ +- + I Tesing of EDI functionality. First I export customer invoice from my company than import that invoice into customer company +- + !python {model: ir.edi.document}: | + import json + order_pool = self.pool.get('purchase.order') + purchase_id = order_pool.search(cr, uid, []) + orders = order_pool.browse(cr, uid, purchase_id) + + if type(orders).__name__ == 'list': + tokens = self.export_edi(cr, uid, orders) + for token in tokens: + document = self.get_document(cr, uid, token) + document = json.loads(document) + edi_doc = [] + for doc in document: + doc.update({'__model': 'sale.order'}) + edi_doc.append(doc) + a = self.import_edi(cr, uid, edi_document = json.dumps(edi_doc)) + else: + tokens = self.export_edi(cr, uid, orders) + for token in tokens: + document = self.get_document(cr, uid, token) + document = json.loads(document) + edi_doc = [] + for doc in document: + doc.update({'__model': 'sale.order'}) + edi_doc.append(doc) + a = self.import_edi(cr, uid, edi_document = json.dumps(edi_doc)) + + From 5ffef81c62fbe2bf2056d65119dadc4d30a2b0e3 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Tue, 30 Aug 2011 11:04:53 +0530 Subject: [PATCH 029/316] [IMP] improve the edi purchase order import and export testing bzr revid: aar@tinyerp.com-20110830053453-ecsqohdm12kp6xao --- addons/purchase/__openerp__.py | 3 +- addons/purchase/edi_purchase_order.py | 4 +- addons/purchase/edi_purchase_order_data.xml | 2 +- addons/purchase/test/edi_purchase_order.yml | 71 +++++++++++++-------- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/addons/purchase/__openerp__.py b/addons/purchase/__openerp__.py index f360d881cf3..21a9184cbb3 100644 --- a/addons/purchase/__openerp__.py +++ b/addons/purchase/__openerp__.py @@ -59,6 +59,7 @@ Dashboard for purchase management that includes: 'report/purchase_report_view.xml', 'board_purchase_view.xml', 'edi_purchase_order_data.xml', + ], 'test': [ 'test/purchase_from_order.yml', @@ -67,7 +68,7 @@ Dashboard for purchase management that includes: 'purchase_unit_test.xml', 'test/procurement_buy.yml', 'test/purchase_report.yml', - #'test/edi_purchase_order.yml', + 'test/edi_purchase_order.yml', ], 'demo': ['purchase_demo.xml'], 'installable': True, diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 1ea43afbb09..8621e33f15b 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -118,14 +118,13 @@ class purchase_order(osv.osv, ir_edi.edi): invoice_line_pool = self.pool.get('account.invoice.line') account_pool = self.pool.get('account.account') stock = self.pool.get('stock.location') - tax_id = [] account_id = [] partner_id = None company_id = None if context is None: context = {} - + print edi_document # import company as a new partner, if type==in then supplier=1, else customer=1 # partner_id field is modified to point to the new partner # company_address data used to add address to new partner @@ -178,7 +177,6 @@ class purchase_order(osv.osv, ir_edi.edi): if document.has_key(key): del document[key] - print edi_document return super(purchase_order,self).edi_import(cr, uid, edi_document, context=context) purchase_order() diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index ab29119bed1..937045d3380 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -45,7 +45,7 @@ Regards, mako Mail Template of Purchase Order For EDI Document purchase.order - + ${object.user_id.user_email or ''} diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml index 2901aeb5e9a..e6ee0c76840 100644 --- a/addons/purchase/test/edi_purchase_order.yml +++ b/addons/purchase/test/edi_purchase_order.yml @@ -1,31 +1,46 @@ - - I Tesing of EDI functionality. First I export customer invoice from my company than import that invoice into customer company + I create a partner which is a my customer +- + !record {model: res.partner, id: res_partner_test20}: + name: jones white + supplier: False + customer: True + opt_out: False +- + I create one Purchase Order +- + !record {model: purchase.order, id: purchase_order_test}: + partner_id: res_partner_test22 + partner_address_id: base.res_partner_address_11 + location_id: stock.stock_location_3 + pricelist_id: 1 + order_line: + - product_id: product.product_product_pc1 + product_uom_qty: 1.0 + product_uom: 1 + price_unit: 150.0 + name: 'basic pc' +- + I Open the sale order +- + !python {model: purchase.order}: | + + orders = self.browse(cr, uid, ref("purchase_order_test")) + import netsvc + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, 'purchase.order',orders.id,'approved', cr) - !python {model: ir.edi.document}: | - import json - order_pool = self.pool.get('purchase.order') - purchase_id = order_pool.search(cr, uid, []) - orders = order_pool.browse(cr, uid, purchase_id) - - if type(orders).__name__ == 'list': - tokens = self.export_edi(cr, uid, orders) - for token in tokens: - document = self.get_document(cr, uid, token) - document = json.loads(document) - edi_doc = [] - for doc in document: - doc.update({'__model': 'sale.order'}) - edi_doc.append(doc) - a = self.import_edi(cr, uid, edi_document = json.dumps(edi_doc)) - else: - tokens = self.export_edi(cr, uid, orders) - for token in tokens: - document = self.get_document(cr, uid, token) - document = json.loads(document) - edi_doc = [] - for doc in document: - doc.update({'__model': 'sale.order'}) - edi_doc.append(doc) - a = self.import_edi(cr, uid, edi_document = json.dumps(edi_doc)) - - + order_pool = self.pool.get('purchase.order') + purchase_id = order_pool.search(cr, uid, ref("purchase_order_test")) + orders = order_pool.browse(cr, uid, purchase_id) + import json + + tokens = self.export_edi(cr, uid, [orders]) + assert tokens, 'Token is not generated' + document = self.get_document(cr, uid, tokens[0]) + document = json.loads(document) + document[0]["__model"] = "purchase.order" + document = json.dumps(document) + a = self.import_edi(cr, uid, edi_document = document) + From 78f10b2fe38236d6c6da452d4e2d3d00d72ef407 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Tue, 30 Aug 2011 18:54:31 +0530 Subject: [PATCH 030/316] [IMP] improve the email template bzr revid: aar@tinyerp.com-20110830132431-4zsut2pz3fudcb5g --- addons/purchase/edi_purchase_order.py | 4 ++ addons/purchase/edi_purchase_order_data.xml | 45 ++++++++++++++++----- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 8621e33f15b..2d719300b8d 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -41,6 +41,9 @@ class purchase_order(osv.osv, ir_edi.edi): 'location_id': True, 'pricelist_id': True, 'validator' : True, + 'amount_tax': True, + 'amount_total': True, + 'amount_untaxed': True, 'order_line': { 'name': True, 'product_qty': True, @@ -102,6 +105,7 @@ class purchase_order(osv.osv, ir_edi.edi): #'paid': inv_comp.paid, #TODO }) edi_doc_list.append(edi_doc) + print "??????????????????????",edi_doc_list return edi_doc_list def edi_import(self, cr, uid, edi_document, context=None): diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index 937045d3380..7351afe4a3f 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -4,7 +4,7 @@ context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -self.pool.get('email.template').generate_mail(cr, +if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase')[1], [object.id], @@ -30,22 +30,47 @@ self.pool.get('email.template').generate_mail(cr, ${object.partner_address_id.email} True + +<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); "> + +<p> Hello ${object.partner_address_id.name and ' ' or ''},</p> +<p> You can click on the following link to preview, print and pay invoice: <br/> + <a href="${object._context.get('edi_web_url_view')}">${object._context.get('edi_web_url_view')} </a> +</p> + + +<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Confirm date: ${object.date_approve or 'n/a'}<br /> Your contact: <a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></p> + +${object.company_id.paypal_account and "<p>It is possible to pay with Paypal: <br/> <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s\"><img src=\"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif\" style=\"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;\"/></a> </p>"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} + +<p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></div> <div> </div> </div> </div> <p> </p> + -Hello ${object.partner_address_id.name}, +Hello ${object.partner_address_id.name and ' ' or ''}, -We just registered the purchase order ${object.name} for ${object.amount_total} for your company ${object.partner_id.name}. -You can click on the following link to preview. +You can click on the following link to preview, print and pay invoice: - ${object._context.get('edi_web_url_view')} + ${object._context.get('edi_web_url_view') or 'n/a'} - Confirmed on ${object.date_approve} - -Regards, - +Order Number: *${object.name}* +Amount: *${object.amount_total}* +Approve date: ${object.date_approve or 'n/a'} +Your contact: ${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''} + +${object.company_id.paypal_account and "It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} + +If you have any question, do not hesitate to reply directly to this e-mail. + +Thank you for choosing our service! + +-- +${object.company_id.name} +Contact: ${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''} + mako Mail Template of Purchase Order For EDI Document purchase.order - ${object.user_id.user_email or ''} + ${object.validator.user_email or ''} From 07881a0c50b00635f5becbb7c0c3b416f34e1263 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Fri, 2 Sep 2011 17:18:53 +0530 Subject: [PATCH 031/316] [REF]:execute method in audittrail_objects_proxy bzr revid: nch@tinyerp.com-20110902114853-z7f1uofjgh8poq0z --- addons/audittrail/audittrail.py | 39 +++++++++++++-------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index bfa6bca8f34..ffb44502ba4 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -292,7 +292,7 @@ class audittrail_objects_proxy(object_proxy): def log_fct(self, db, uid, model, method, fct_src, *args): """ - Logging function: This function is performs logging oprations according to method + Logging function: This function is performs logging operations according to method @param db: the current database @param uid: the current user’s ID for security checks, @param object: Object who's values are being changed @@ -482,41 +482,32 @@ class audittrail_objects_proxy(object_proxy): cr = pooler.get_db(db).cursor() cr.autocommit(True) logged_uids = [] + rule = False + ignore_methods = ['default_get','read','fields_view_get','fields_get','search', + 'search_count','name_search','name_get','get','request_get', + 'get_sc', 'unlink', 'write', 'create'] fct_src = super(audittrail_objects_proxy, self).execute - - def my_fct(db, uid, model, method, *args): - rule = False + try: model_ids = model_pool.search(cr, uid, [('model', '=', model)]) model_id = model_ids and model_ids[0] or False - - for model_name in pool.obj_list(): - if model_name == 'audittrail.rule': - rule = True - if not rule: - return fct_src(db, uid_orig, model, method, *args) - if not model_id: - return fct_src(db, uid_orig, model, method, *args) - + if 'audittrail.rule' in pool.obj_list(): + rule = True + if not rule or not model_id: + return fct_src(db, uid_orig, model, method, *args) rule_ids = rule_pool.search(cr, uid, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) if not rule_ids: return fct_src(db, uid_orig, model, method, *args) - for thisrule in rule_pool.browse(cr, uid, rule_ids): - for user in thisrule.user_id: - logged_uids.append(user.id) + for model_rule in rule_pool.browse(cr, uid, rule_ids): + logged_uids += map(lambda x:x.id, model_rule.user_id) if not logged_uids or uid in logged_uids: if method in ('read', 'write', 'create', 'unlink'): - if getattr(thisrule, 'log_' + method): + if getattr(model_rule, 'log_' + method): return self.log_fct(db, uid_orig, model, method, fct_src, *args) - - elif method not in ('default_get','read','fields_view_get','fields_get','search','search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create'): - if thisrule.log_action: + elif method not in ignore_methods: + if model_rule.log_action: return self.log_fct(db, uid_orig, model, method, fct_src, *args) - return fct_src(db, uid_orig, model, method, *args) - try: - res = my_fct(db, uid, model, method, *args) - return res finally: cr.close() From 2fef7cd890150c20b4cb9835d601263de1ba5632 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Mon, 5 Sep 2011 14:39:26 +0530 Subject: [PATCH 032/316] [IMP]:refactored with speed improvement:get_value_text method bzr revid: nch@tinyerp.com-20110905090926-jjklwr3p12sbjzl2 --- addons/audittrail/audittrail.py | 50 +++++++++++---------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index ffb44502ba4..0780679f49c 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -203,37 +203,22 @@ class audittrail_objects_proxy(object_proxy): if field_name in('__last_update','id'): return values pool = pooler.get_pool(cr.dbname) - field_pool = pool.get('ir.model.fields') - model_pool = pool.get('ir.model') obj_pool = pool.get(model.model) - if obj_pool._inherits: - inherits_ids = model_pool.search(cr, uid, [('model', '=', obj_pool._inherits.keys()[0])]) - field_ids = field_pool.search(cr, uid, [('name', '=', field_name), ('model_id', 'in', (model.id, inherits_ids[0]))]) - else: - field_ids = field_pool.search(cr, uid, [('name', '=', field_name), ('model_id', '=', model.id)]) - field_id = field_ids and field_ids[0] or False - assert field_id, _("'%s' field does not exist in '%s' model" %(field_name, model.model)) - - field = field_pool.read(cr, uid, field_id) - relation_model = field['relation'] - relation_model_pool = relation_model and pool.get(relation_model) or False - - if field['ttype'] == 'many2one': - res = False - relation_id = False - if values and type(values) == tuple: - relation_id = values[0] - if relation_id and relation_model_pool: - relation_model_object = relation_model_pool.read(cr, uid, relation_id, [relation_model_pool._rec_name]) - res = relation_model_object[relation_model_pool._rec_name] - return res - - elif field['ttype'] in ('many2many','one2many'): - res = [] - for relation_model_object in relation_model_pool.read(cr, uid, values, [relation_model_pool._rec_name]): - res.append(relation_model_object[relation_model_pool._rec_name]) - return res - + field_obj = obj_pool._all_columns.get(field_name, False) + assert field_obj, _("'%s' field does not exist in '%s' model" %(field_name, model.model)) + field_obj = field_obj.column + if field_obj._obj: + relation_model_pool = pool.get(field_obj._obj) + relational_rec_name = relation_model_pool._rec_name + if field_obj._type == 'many2one': + if values and isinstance(values, tuple): + if values[0]: + relation_model_object = relation_model_pool.read(cr, uid, values[0], [relational_rec_name]) + return relation_model_object.get(relational_rec_name) + return False + elif field_obj._type in ('many2many','one2many'): + data = relation_model_pool.read(cr, uid, values, [relational_rec_name]) + return map(lambda x:x.get(relational_rec_name, False), data) return values def create_log_line(self, cr, uid, log_id, model, lines=[]): @@ -482,7 +467,6 @@ class audittrail_objects_proxy(object_proxy): cr = pooler.get_db(db).cursor() cr.autocommit(True) logged_uids = [] - rule = False ignore_methods = ['default_get','read','fields_view_get','fields_get','search', 'search_count','name_search','name_get','get','request_get', 'get_sc', 'unlink', 'write', 'create'] @@ -490,9 +474,7 @@ class audittrail_objects_proxy(object_proxy): try: model_ids = model_pool.search(cr, uid, [('model', '=', model)]) model_id = model_ids and model_ids[0] or False - if 'audittrail.rule' in pool.obj_list(): - rule = True - if not rule or not model_id: + if not ('audittrail.rule' in pool.obj_list()) or not model_id: return fct_src(db, uid_orig, model, method, *args) rule_ids = rule_pool.search(cr, uid, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) if not rule_ids: From 9ebdf040f574d1da0697435fdc4acae864085aec Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Mon, 5 Sep 2011 15:08:41 +0530 Subject: [PATCH 033/316] [IMP]:refactored create_log_line method bzr revid: nch@tinyerp.com-20110905093841-uk7nke7e36gsf4ig --- addons/audittrail/audittrail.py | 39 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 0780679f49c..99382797d72 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -235,43 +235,36 @@ class audittrail_objects_proxy(object_proxy): model_pool = pool.get('ir.model') field_pool = pool.get('ir.model.fields') log_line_pool = pool.get('audittrail.log.line') - #start Loop for line in lines: - if line['name'] in('__last_update','id'): + if line['name'] in ('__last_update','id'): continue + field_obj = obj_pool._all_columns.get(line['name'], False) + assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) + field_obj = field_obj.column + old_value = line.get('old_value', '') + new_value = line.get('new_value', '') + old_value_text = line.get('old_value_text', '') + new_value_text = line.get('new_value_text', '') + search_models = [ model.id ] if obj_pool._inherits: - inherits_ids = model_pool.search(cr, uid, [('model', '=', obj_pool._inherits.keys()[0])]) - field_ids = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', (model.id, inherits_ids[0]))]) - else: - field_ids = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', '=', model.id)]) - field_id = field_ids and field_ids[0] or False - assert field_id, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) - - field = field_pool.read(cr, uid, field_id) - old_value = 'old_value' in line and line['old_value'] or '' - new_value = 'new_value' in line and line['new_value'] or '' - old_value_text = 'old_value_text' in line and line['old_value_text'] or '' - new_value_text = 'new_value_text' in line and line['new_value_text'] or '' - + search_models += model_pool.search(cr, uid, [('model', 'in', obj_pool._inherits.keys())]) + field_id = field_pool.search(cr, uid, [('name', '=', line['name']), ('model_id', 'in', search_models)]) if old_value_text == new_value_text: continue - if field['ttype'] == 'many2one': - if type(old_value) == tuple: - old_value = old_value[0] - if type(new_value) == tuple: - new_value = new_value[0] + if field_obj._type == 'many2one': + old_value = isinstance(old_value, tuple) and old_value[0] or old_value + new_value = isinstance(new_value, tuple) and new_value[0] or new_value vals = { "log_id": log_id, - "field_id": field_id, + "field_id": field_id and field_id[0] or False, "old_value": old_value, "new_value": new_value, "old_value_text": old_value_text, "new_value_text": new_value_text, - "field_description": field['field_description'] + "field_description": field_obj.string } line_id = log_line_pool.create(cr, uid, vals) cr.commit() - #End Loop return True From 2a828b8f5e86ce16bce6a114a34a8f893bed7c6e Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Mon, 5 Sep 2011 17:38:46 +0530 Subject: [PATCH 034/316] [IMP]:refactored log_fct to include create for o2m, m2m method bzr revid: nch@tinyerp.com-20110905120846-sletd1fvcfloqdxy --- addons/audittrail/audittrail.py | 55 +++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 99382797d72..841eda00d29 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -292,31 +292,38 @@ class audittrail_objects_proxy(object_proxy): model_id = model_ids and model_ids[0] or False assert model_id, _("'%s' Model does not exist..." %(model)) model = model_pool.browse(cr, uid, model_id) - + relational_table_log = args and args[-1] == 'child_relation_log' or False if method in ('create'): - res_id = fct_src(db, uid_orig, model.model, method, *args) - cr.commit() - resource = resource_pool.read(cr, uid, res_id, args[0].keys()) - vals = { - "method": method, - "object_id": model.id, - "user_id": uid_orig, - "res_id": resource['id'], - } - if 'id' in resource: - del resource['id'] - log_id = log_pool.create(cr, uid, vals) - lines = [] - for field in resource: - line = { - 'name': field, - 'new_value': resource[field], - 'new_value_text': self.get_value_text(cr, uid, field, resource[field], model) - } - lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) - - cr.commit() + fields_to_read = [] + if relational_table_log: + res_id = args[0] + else: + res_id = fct_src(db, uid_orig, model.model, method, *args) + cr.commit() + fields_to_read = args[0].keys() + resource = resource_pool.read(cr, uid, res_id, fields_to_read) + if not isinstance(resource, list): + resource = [resource] + vals = { 'method': method, 'object_id': model.id,'user_id': uid_orig} + for resource_data in resource: + vals.update({'res_id': resource_data['id']}) + if 'id' in resource_data: + del resource_data['id'] + log_id = log_pool.create(cr, uid, vals) + lines = [] + for field in resource_data: + field_obj = resource_pool._all_columns.get(field, False) + field_obj = field_obj.column + if field_obj._type in ('one2many','many2many'): + self.log_fct(db, uid, field_obj._obj, method, None, resource_data[field], 'child_relation_log') + line = { + 'name': field, + 'new_value': resource_data[field], + 'new_value_text': self.get_value_text(cr, uid, field, resource_data[field], model) + } + lines.append(line) + self.create_log_line(cr, uid, log_id, model, lines) + cr.commit() cr.close() return res_id From 43ff15c84d7f6f674e0201a2674b2a5a4e3c7082 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 11:01:24 +0530 Subject: [PATCH 035/316] [IMP]:get_value_text to use name_get for x2m and simply return [1] arg for m2o tuple bzr revid: nch@tinyerp.com-20110906053124-a3kw3j2g3weln60q --- addons/audittrail/audittrail.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 841eda00d29..1d42000488d 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -204,21 +204,19 @@ class audittrail_objects_proxy(object_proxy): return values pool = pooler.get_pool(cr.dbname) obj_pool = pool.get(model.model) - field_obj = obj_pool._all_columns.get(field_name, False) + field_obj = obj_pool._all_columns.get(field_name) assert field_obj, _("'%s' field does not exist in '%s' model" %(field_name, model.model)) field_obj = field_obj.column if field_obj._obj: relation_model_pool = pool.get(field_obj._obj) relational_rec_name = relation_model_pool._rec_name if field_obj._type == 'many2one': - if values and isinstance(values, tuple): - if values[0]: - relation_model_object = relation_model_pool.read(cr, uid, values[0], [relational_rec_name]) - return relation_model_object.get(relational_rec_name) - return False + if values: + return values[1] + return values elif field_obj._type in ('many2many','one2many'): - data = relation_model_pool.read(cr, uid, values, [relational_rec_name]) - return map(lambda x:x.get(relational_rec_name, False), data) + data = relation_model_pool.name_get(cr, uid, values) + return map(lambda x:x[1], data) return values def create_log_line(self, cr, uid, log_id, model, lines=[]): @@ -312,7 +310,7 @@ class audittrail_objects_proxy(object_proxy): log_id = log_pool.create(cr, uid, vals) lines = [] for field in resource_data: - field_obj = resource_pool._all_columns.get(field, False) + field_obj = resource_pool._all_columns.get(field) field_obj = field_obj.column if field_obj._type in ('one2many','many2many'): self.log_fct(db, uid, field_obj._obj, method, None, resource_data[field], 'child_relation_log') From 1947eed2df667bfd59b7c42306e19ab390170e96 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 11:24:31 +0530 Subject: [PATCH 036/316] [IMP]:support for x2m log unlink bzr revid: nch@tinyerp.com-20110906055431-a87bvbm0o7p1hts5 --- addons/audittrail/audittrail.py | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 1d42000488d..3f4417a15bb 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -359,33 +359,31 @@ class audittrail_objects_proxy(object_proxy): elif method in ('unlink'): res_ids = args[0] + res = False old_values = {} for res_id in res_ids: old_values[res_id] = resource_pool.read(cr, uid, res_id) - + vals = {'method': method,'object_id': model.id,'user_id': uid_orig} for res_id in res_ids: - vals = { - "method": method, - "object_id": model.id, - "user_id": uid_orig, - "res_id": res_id, - - } + vals.update({'res_id': res_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in old_values[res_id]: - if field in ('id'): - continue + if field == 'id': continue + field_obj = resource_pool._all_columns.get(field) + field_obj = field_obj.column + if field_obj._type in ('one2many','many2many'): + self.log_fct(db, uid, field_obj._obj, method, None, old_values[res_id][field], 'child_relation_log') line = { 'name': field, 'old_value': old_values[res_id][field], 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model) } lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) - res = fct_src(db, uid_orig, model.model, method, *args) - cr.commit() + if not relational_table_log: + res = fct_src(db, uid_orig, model.model, method, *args) + cr.commit() cr.close() return res else: From d213821ea0dc2b000f95df025be8f45cefa63330 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 11:52:41 +0530 Subject: [PATCH 037/316] [IMP]:x2m logging when there is any action execute like on_change,copy etc bzr revid: nch@tinyerp.com-20110906062241-373t8wqelc9jsyk9 --- addons/audittrail/audittrail.py | 46 +++++++++++++++------------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 3f4417a15bb..ed4fc5a551d 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -236,7 +236,7 @@ class audittrail_objects_proxy(object_proxy): for line in lines: if line['name'] in ('__last_update','id'): continue - field_obj = obj_pool._all_columns.get(line['name'], False) + field_obj = obj_pool._all_columns.get(line['name']) assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) field_obj = field_obj.column old_value = line.get('old_value', '') @@ -250,8 +250,8 @@ class audittrail_objects_proxy(object_proxy): if old_value_text == new_value_text: continue if field_obj._type == 'many2one': - old_value = isinstance(old_value, tuple) and old_value[0] or old_value - new_value = isinstance(new_value, tuple) and new_value[0] or new_value + old_value = old_value[0] + new_value = new_value[0] vals = { "log_id": log_id, "field_id": field_id and field_id[0] or False, @@ -305,8 +305,7 @@ class audittrail_objects_proxy(object_proxy): vals = { 'method': method, 'object_id': model.id,'user_id': uid_orig} for resource_data in resource: vals.update({'res_id': resource_data['id']}) - if 'id' in resource_data: - del resource_data['id'] + del resource_data['id'] log_id = log_pool.create(cr, uid, vals) lines = [] for field in resource_data: @@ -393,38 +392,36 @@ class audittrail_objects_proxy(object_proxy): res_ids = args[0] old_values = {} fields = [] - if len(args)>1 and type(args[1]) == dict: + if len(args) > 1 and isinstance(args[1], dict): fields = args[1].keys() - if type(res_ids) in (long, int): + if isinstance(res_ids, (long, int)): res_ids = [res_ids] if res_ids: - for resource in resource_pool.read(cr, uid, res_ids): + resource_data = resource_pool.read(cr, uid, res_ids) + for resource in resource_data: resource_id = resource['id'] - if 'id' in resource: - del resource['id'] + del resource['id'] old_values_text = {} old_value = {} for field in resource.keys(): + field_obj = resource_pool._all_columns.get(field) + field_obj = field_obj.column + if field_obj._type in ('one2many','many2many'): + self.log_fct(db, uid, field_obj._obj, method, None, resource[field], 'child_relation_log') old_value[field] = resource[field] old_values_text[field] = self.get_value_text(cr, uid, field, resource[field], model) old_values[resource_id] = {'text':old_values_text, 'value': old_value} - - res = fct_src(db, uid_orig, model.model, method, *args) - cr.commit() + if not relational_table_log: + res = fct_src(db, uid_orig, model.model, method, *args) + cr.commit() if res_ids: - for resource in resource_pool.read(cr, uid, res_ids): + resource_data = resource_pool.read(cr, uid, res_ids) + vals = {'method': method,'object_id': model.id,'user_id': uid_orig } + for resource in resource_data: resource_id = resource['id'] - if 'id' in resource: - del resource['id'] - vals = { - "method": method, - "object_id": model.id, - "user_id": uid_orig, - "res_id": resource_id, - } - - + del resource['id'] + vals.update({'res_id': resource_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in resource.keys(): @@ -436,7 +433,6 @@ class audittrail_objects_proxy(object_proxy): 'old_value_text': old_values[resource_id]['text'][field] } lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) cr.commit() cr.close() From c70d21b6227dac93a0765e80f80a80a3718c532e Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 12:24:16 +0530 Subject: [PATCH 038/316] [IMP]:refactored: removed code duplication bzr revid: nch@tinyerp.com-20110906065416-33abo0zg1e6n55v5 --- addons/audittrail/audittrail.py | 85 +++++++++++---------------------- 1 file changed, 28 insertions(+), 57 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index ed4fc5a551d..4fd99d7bba3 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -250,8 +250,8 @@ class audittrail_objects_proxy(object_proxy): if old_value_text == new_value_text: continue if field_obj._type == 'many2one': - old_value = old_value[0] - new_value = new_value[0] + old_value = old_value and old_value[0] or old_value + new_value = new_value and new_value[0] or new_value vals = { "log_id": log_id, "field_id": field_id and field_id[0] or False, @@ -439,90 +439,61 @@ class audittrail_objects_proxy(object_proxy): return res return True - - - def execute(self, db, uid, model, method, *args, **kw): + def audit_log_call(self, db, uid, model, method, action_type, *args, **argv): """ Overrides Object Proxy execute method @param db: the current database @param uid: the current user's ID for security checks, @param object: Object who's values are being changed @param method: get any method and create log - + @param action_type: either 'execute' or 'workflow' @return: Returns result as per method of Object proxy """ uid_orig = uid uid = 1 pool = pooler.get_pool(db) + logged_uids = [] model_pool = pool.get('ir.model') rule_pool = pool.get('audittrail.rule') cr = pooler.get_db(db).cursor() cr.autocommit(True) - logged_uids = [] - ignore_methods = ['default_get','read','fields_view_get','fields_get','search', - 'search_count','name_search','name_get','get','request_get', - 'get_sc', 'unlink', 'write', 'create'] - fct_src = super(audittrail_objects_proxy, self).execute + if action_type == 'execute': + ignore_methods = ['default_get','read','fields_view_get','fields_get','search', + 'search_count','name_search','name_get','get','request_get', + 'get_sc', 'unlink', 'write', 'create'] + fct_src = super(audittrail_objects_proxy, self).execute + else: + fct_src = super(audittrail_objects_proxy, self).exec_workflow try: model_ids = model_pool.search(cr, uid, [('model', '=', model)]) model_id = model_ids and model_ids[0] or False if not ('audittrail.rule' in pool.obj_list()) or not model_id: - return fct_src(db, uid_orig, model, method, *args) + return fct_src(db, uid_orig, model, method, *args, **argv) rule_ids = rule_pool.search(cr, uid, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) if not rule_ids: - return fct_src(db, uid_orig, model, method, *args) - + return fct_src(db, uid_orig, model, method, *args, **argv) for model_rule in rule_pool.browse(cr, uid, rule_ids): logged_uids += map(lambda x:x.id, model_rule.user_id) if not logged_uids or uid in logged_uids: - if method in ('read', 'write', 'create', 'unlink'): - if getattr(model_rule, 'log_' + method): + if action_type == 'execute': + if method in ('read', 'write', 'create', 'unlink'): + if getattr(model_rule, 'log_' + method): + return self.log_fct(db, uid_orig, model, method, fct_src, *args) + elif method not in ignore_methods: + if model_rule.log_action: + return self.log_fct(db, uid_orig, model, method, fct_src, *args) + else: + if model_rule.log_workflow: return self.log_fct(db, uid_orig, model, method, fct_src, *args) - elif method not in ignore_methods: - if model_rule.log_action: - return self.log_fct(db, uid_orig, model, method, fct_src, *args) - return fct_src(db, uid_orig, model, method, *args) + return fct_src(db, uid_orig, model, method, *args, **argv) finally: cr.close() + def execute(self, db, uid, model, method, *args, **argv): + return self.audit_log_call(db, uid, model, method, 'execute', *args, **argv) + def exec_workflow(self, db, uid, model, method, *args, **argv): - uid_orig = uid - uid = 1 - - pool = pooler.get_pool(db) - logged_uids = [] - fct_src = super(audittrail_objects_proxy, self).exec_workflow - field = method - rule = False - model_pool = pool.get('ir.model') - rule_pool = pool.get('audittrail.rule') - cr = pooler.get_db(db).cursor() - cr.autocommit(True) - try: - model_ids = model_pool.search(cr, uid, [('model', '=', model)]) - for obj_name in pool.obj_list(): - if obj_name == 'audittrail.rule': - rule = True - if not rule: - return super(audittrail_objects_proxy, self).exec_workflow(db, uid_orig, model, method, *args, **argv) - if not model_ids: - return super(audittrail_objects_proxy, self).exec_workflow(db, uid_orig, model, method, *args, **argv) - - rule_ids = rule_pool.search(cr, uid, [('object_id', 'in', model_ids), ('state', '=', 'subscribed')]) - if not rule_ids: - return super(audittrail_objects_proxy, self).exec_workflow(db, uid_orig, model, method, *args, **argv) - - for thisrule in rule_pool.browse(cr, uid, rule_ids): - for user in thisrule.user_id: - logged_uids.append(user.id) - if not logged_uids or uid in logged_uids: - if thisrule.log_workflow: - return self.log_fct(db, uid_orig, model, method, fct_src, *args) - return super(audittrail_objects_proxy, self).exec_workflow(db, uid_orig, model, method, *args, **argv) - - return True - finally: - cr.close() + return self.audit_log_call(db, uid, model, method, 'workflow', *args, **argv) audittrail_objects_proxy() From b8596288a8c793c7e1b176d570f291668ab22a1a Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 15:04:53 +0530 Subject: [PATCH 039/316] [IMP]:removedget_value_text to refactore the code..more improvements coming bzr revid: nch@tinyerp.com-20110906093453-c6z7wj8178w6o75g --- addons/audittrail/audittrail.py | 112 +++++++++++++++----------------- 1 file changed, 53 insertions(+), 59 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 4fd99d7bba3..41205982101 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -187,38 +187,6 @@ audittrail_log_line() class audittrail_objects_proxy(object_proxy): """ Uses Object proxy for auditing changes on object of subscribed Rules""" - def get_value_text(self, cr, uid, field_name, values, model, context=None): - """ - Gets textual values for the fields - e.g.: For field of type many2one it gives its name value instead of id - - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param field_name: List of fields for text values - @param values: Values for field to be converted into textual values - @return: values: List of textual values for given fields - """ - if not context: - context = {} - if field_name in('__last_update','id'): - return values - pool = pooler.get_pool(cr.dbname) - obj_pool = pool.get(model.model) - field_obj = obj_pool._all_columns.get(field_name) - assert field_obj, _("'%s' field does not exist in '%s' model" %(field_name, model.model)) - field_obj = field_obj.column - if field_obj._obj: - relation_model_pool = pool.get(field_obj._obj) - relational_rec_name = relation_model_pool._rec_name - if field_obj._type == 'many2one': - if values: - return values[1] - return values - elif field_obj._type in ('many2many','one2many'): - data = relation_model_pool.name_get(cr, uid, values) - return map(lambda x:x[1], data) - return values - def create_log_line(self, cr, uid, log_id, model, lines=[]): """ Creates lines for changed fields with its old and new values @@ -234,8 +202,6 @@ class audittrail_objects_proxy(object_proxy): field_pool = pool.get('ir.model.fields') log_line_pool = pool.get('audittrail.log.line') for line in lines: - if line['name'] in ('__last_update','id'): - continue field_obj = obj_pool._all_columns.get(line['name']) assert field_obj, _("'%s' field does not exist in '%s' model" %(line['name'], model.model)) field_obj = field_obj.column @@ -279,7 +245,6 @@ class audittrail_objects_proxy(object_proxy): """ uid_orig = uid uid = 1 - res2 = args pool = pooler.get_pool(db) cr = pooler.get_db(db).cursor() resource_pool = pool.get(model) @@ -303,6 +268,7 @@ class audittrail_objects_proxy(object_proxy): if not isinstance(resource, list): resource = [resource] vals = { 'method': method, 'object_id': model.id,'user_id': uid_orig} + new_value_text = '' for resource_data in resource: vals.update({'res_id': resource_data['id']}) del resource_data['id'] @@ -311,12 +277,18 @@ class audittrail_objects_proxy(object_proxy): for field in resource_data: field_obj = resource_pool._all_columns.get(field) field_obj = field_obj.column + new_value_text = resource_data[field] + if field in ('__last_update', 'id'):continue if field_obj._type in ('one2many','many2many'): self.log_fct(db, uid, field_obj._obj, method, None, resource_data[field], 'child_relation_log') + data = pool.get(field_obj._obj).name_get(cr, uid, resource_data[field]) + new_value_text = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + new_value_text = resource_data[field] and resource_data[field][1] or resource_data[field] line = { 'name': field, 'new_value': resource_data[field], - 'new_value_text': self.get_value_text(cr, uid, field, resource_data[field], model) + 'new_value_text': new_value_text } lines.append(line) self.create_log_line(cr, uid, log_id, model, lines) @@ -328,29 +300,29 @@ class audittrail_objects_proxy(object_proxy): res_ids = args[0] old_values = {} res = fct_src(db, uid_orig, model.model, method, *args) - if type(res) == list: - for v in res: - old_values[v['id']] = v - else: - old_values[res['id']] = res + map(lambda x:old_values.setdefault(x['id'], x), res) + vals = {'method': method,'object_id': model.id,'user_id': uid_orig} + old_value_text = '' for res_id in old_values: - vals = { - "method": method, - "object_id": model.id, - "user_id": uid_orig, - "res_id": res_id, - - } + vals.update({'res_id': res_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in old_values[res_id]: + if field in ('__last_update', 'id'):continue + field_obj = resource_pool._all_columns.get(field) + field_obj = field_obj.column + old_value_text = old_values[res_id][field] + if field_obj._type in ('one2many','many2many'): + data = pool.get(field_obj._obj).name_get(cr, uid, old_values[res_id][field]) + old_value_text = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + old_value_text = old_values[res_id][field] and old_values[res_id][field][1] or old_values[res_id][field] line = { - 'name': field, - 'old_value': old_values[res_id][field], - 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model) - } + 'name': field, + 'old_value': old_values[res_id][field], + 'old_value_text': old_value_text + } lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) cr.commit() cr.close() @@ -363,20 +335,26 @@ class audittrail_objects_proxy(object_proxy): for res_id in res_ids: old_values[res_id] = resource_pool.read(cr, uid, res_id) vals = {'method': method,'object_id': model.id,'user_id': uid_orig} + old_value_text = '' for res_id in res_ids: vals.update({'res_id': res_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in old_values[res_id]: - if field == 'id': continue + if field in ('__last_update', 'id'):continue field_obj = resource_pool._all_columns.get(field) field_obj = field_obj.column + old_value_text = old_values[res_id][field] if field_obj._type in ('one2many','many2many'): self.log_fct(db, uid, field_obj._obj, method, None, old_values[res_id][field], 'child_relation_log') + data = pool.get(field_obj._obj).name_get(cr, uid, old_values[res_id][field]) + old_value_text = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + old_value_text = old_values[res_id][field] and old_values[res_id][field][1] or old_values[res_id][field] line = { 'name': field, 'old_value': old_values[res_id][field], - 'old_value_text': self.get_value_text(cr, uid, field, old_values[res_id][field], model) + 'old_value_text': old_value_text } lines.append(line) self.create_log_line(cr, uid, log_id, model, lines) @@ -398,26 +376,33 @@ class audittrail_objects_proxy(object_proxy): res_ids = [res_ids] if res_ids: resource_data = resource_pool.read(cr, uid, res_ids) + old_text = '' for resource in resource_data: resource_id = resource['id'] del resource['id'] old_values_text = {} old_value = {} for field in resource.keys(): + if field in ('__last_update', 'id'):continue field_obj = resource_pool._all_columns.get(field) field_obj = field_obj.column + old_text = resource[field] if field_obj._type in ('one2many','many2many'): - self.log_fct(db, uid, field_obj._obj, method, None, resource[field], 'child_relation_log') + self.log_fct(db, uid, field_obj._obj, method, None, resource[field], 'child_relation_log') + data = pool.get(field_obj._obj).name_get(cr, uid, resource[field]) + old_text = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + old_text = resource[field] and resource[field][1] or resource[field] old_value[field] = resource[field] - old_values_text[field] = self.get_value_text(cr, uid, field, resource[field], model) + old_values_text[field] = old_text old_values[resource_id] = {'text':old_values_text, 'value': old_value} if not relational_table_log: res = fct_src(db, uid_orig, model.model, method, *args) cr.commit() - if res_ids: resource_data = resource_pool.read(cr, uid, res_ids) vals = {'method': method,'object_id': model.id,'user_id': uid_orig } + old_value_text = '' for resource in resource_data: resource_id = resource['id'] del resource['id'] @@ -425,11 +410,20 @@ class audittrail_objects_proxy(object_proxy): log_id = log_pool.create(cr, uid, vals) lines = [] for field in resource.keys(): + if field in ('__last_update', 'id'):continue + field_obj = resource_pool._all_columns.get(field) + field_obj = field_obj.column + old_value_text = resource[field] + if field_obj._type in ('one2many','many2many'): + data = pool.get(field_obj._obj).name_get(cr, uid, resource[field]) + old_value_text = map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + old_value_text = resource[field] and resource[field][1] or resource[field] line = { 'name': field, 'new_value': resource[field], 'old_value': old_values[resource_id]['value'][field], - 'new_value_text': self.get_value_text(cr, uid, field, resource[field], model), + 'new_value_text': old_value_text, 'old_value_text': old_values[resource_id]['text'][field] } lines.append(line) From dbd40832d51837844fbf0a94e842c41defbc56dc Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 16:19:49 +0530 Subject: [PATCH 040/316] [REF]:more refactoring bzr revid: nch@tinyerp.com-20110906104949-i6uxzcdden0pq71a --- addons/audittrail/audittrail.py | 75 +++++++++------------------------ 1 file changed, 21 insertions(+), 54 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 41205982101..625d4d46072 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -231,7 +231,17 @@ class audittrail_objects_proxy(object_proxy): cr.commit() return True - + def get_x2m_m2o_values(self, cr, db, uid, pool, resource_pool, method, field, value, recursive=True): + field_obj = (resource_pool._all_columns.get(field)).column + if field_obj._type in ('one2many','many2many'): + if recursive: + self.log_fct(db, uid, field_obj._obj, method, None, value, 'child_relation_log') + data = pool.get(field_obj._obj).name_get(cr, uid, value) + return map(lambda x:x[1], data) + elif field_obj._type == 'many2one': + return value and value[1] or value + return False + def log_fct(self, db, uid, model, method, fct_src, *args): """ Logging function: This function is performs logging operations according to method @@ -268,27 +278,18 @@ class audittrail_objects_proxy(object_proxy): if not isinstance(resource, list): resource = [resource] vals = { 'method': method, 'object_id': model.id,'user_id': uid_orig} - new_value_text = '' for resource_data in resource: vals.update({'res_id': resource_data['id']}) del resource_data['id'] log_id = log_pool.create(cr, uid, vals) lines = [] for field in resource_data: - field_obj = resource_pool._all_columns.get(field) - field_obj = field_obj.column - new_value_text = resource_data[field] if field in ('__last_update', 'id'):continue - if field_obj._type in ('one2many','many2many'): - self.log_fct(db, uid, field_obj._obj, method, None, resource_data[field], 'child_relation_log') - data = pool.get(field_obj._obj).name_get(cr, uid, resource_data[field]) - new_value_text = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - new_value_text = resource_data[field] and resource_data[field][1] or resource_data[field] + ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource_data[field]) line = { 'name': field, 'new_value': resource_data[field], - 'new_value_text': new_value_text + 'new_value_text': ret_val and ret_val or resource_data[field] } lines.append(line) self.create_log_line(cr, uid, log_id, model, lines) @@ -302,25 +303,17 @@ class audittrail_objects_proxy(object_proxy): res = fct_src(db, uid_orig, model.model, method, *args) map(lambda x:old_values.setdefault(x['id'], x), res) vals = {'method': method,'object_id': model.id,'user_id': uid_orig} - old_value_text = '' for res_id in old_values: vals.update({'res_id': res_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in old_values[res_id]: if field in ('__last_update', 'id'):continue - field_obj = resource_pool._all_columns.get(field) - field_obj = field_obj.column - old_value_text = old_values[res_id][field] - if field_obj._type in ('one2many','many2many'): - data = pool.get(field_obj._obj).name_get(cr, uid, old_values[res_id][field]) - old_value_text = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - old_value_text = old_values[res_id][field] and old_values[res_id][field][1] or old_values[res_id][field] + ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, old_values[res_id][field], False) line = { 'name': field, 'old_value': old_values[res_id][field], - 'old_value_text': old_value_text + 'old_value_text': ret_val and ret_val or old_values[res_id][field] } lines.append(line) self.create_log_line(cr, uid, log_id, model, lines) @@ -335,26 +328,17 @@ class audittrail_objects_proxy(object_proxy): for res_id in res_ids: old_values[res_id] = resource_pool.read(cr, uid, res_id) vals = {'method': method,'object_id': model.id,'user_id': uid_orig} - old_value_text = '' for res_id in res_ids: vals.update({'res_id': res_id}) log_id = log_pool.create(cr, uid, vals) lines = [] for field in old_values[res_id]: if field in ('__last_update', 'id'):continue - field_obj = resource_pool._all_columns.get(field) - field_obj = field_obj.column - old_value_text = old_values[res_id][field] - if field_obj._type in ('one2many','many2many'): - self.log_fct(db, uid, field_obj._obj, method, None, old_values[res_id][field], 'child_relation_log') - data = pool.get(field_obj._obj).name_get(cr, uid, old_values[res_id][field]) - old_value_text = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - old_value_text = old_values[res_id][field] and old_values[res_id][field][1] or old_values[res_id][field] + ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, old_values[res_id][field]) line = { 'name': field, 'old_value': old_values[res_id][field], - 'old_value_text': old_value_text + 'old_value_text': ret_val and ret_val or old_values[res_id][field] } lines.append(line) self.create_log_line(cr, uid, log_id, model, lines) @@ -376,7 +360,6 @@ class audittrail_objects_proxy(object_proxy): res_ids = [res_ids] if res_ids: resource_data = resource_pool.read(cr, uid, res_ids) - old_text = '' for resource in resource_data: resource_id = resource['id'] del resource['id'] @@ -384,17 +367,9 @@ class audittrail_objects_proxy(object_proxy): old_value = {} for field in resource.keys(): if field in ('__last_update', 'id'):continue - field_obj = resource_pool._all_columns.get(field) - field_obj = field_obj.column - old_text = resource[field] - if field_obj._type in ('one2many','many2many'): - self.log_fct(db, uid, field_obj._obj, method, None, resource[field], 'child_relation_log') - data = pool.get(field_obj._obj).name_get(cr, uid, resource[field]) - old_text = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - old_text = resource[field] and resource[field][1] or resource[field] + ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource[field]) old_value[field] = resource[field] - old_values_text[field] = old_text + old_values_text[field] = ret_val and ret_val or resource[field] old_values[resource_id] = {'text':old_values_text, 'value': old_value} if not relational_table_log: res = fct_src(db, uid_orig, model.model, method, *args) @@ -402,7 +377,6 @@ class audittrail_objects_proxy(object_proxy): if res_ids: resource_data = resource_pool.read(cr, uid, res_ids) vals = {'method': method,'object_id': model.id,'user_id': uid_orig } - old_value_text = '' for resource in resource_data: resource_id = resource['id'] del resource['id'] @@ -411,19 +385,12 @@ class audittrail_objects_proxy(object_proxy): lines = [] for field in resource.keys(): if field in ('__last_update', 'id'):continue - field_obj = resource_pool._all_columns.get(field) - field_obj = field_obj.column - old_value_text = resource[field] - if field_obj._type in ('one2many','many2many'): - data = pool.get(field_obj._obj).name_get(cr, uid, resource[field]) - old_value_text = map(lambda x:x[1], data) - elif field_obj._type == 'many2one': - old_value_text = resource[field] and resource[field][1] or resource[field] + ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource[field], False) line = { 'name': field, 'new_value': resource[field], 'old_value': old_values[resource_id]['value'][field], - 'new_value_text': old_value_text, + 'new_value_text': ret_val and ret_val or resource[field], 'old_value_text': old_values[resource_id]['text'][field] } lines.append(line) From 1dce682a32d0d20092553933921056df42a8d145 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Tue, 6 Sep 2011 17:57:35 +0530 Subject: [PATCH 041/316] [REF] bzr revid: nch@tinyerp.com-20110906122735-4ikr703mpzbiav5b --- addons/audittrail/audittrail.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 625d4d46072..244f26fba3f 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -266,7 +266,7 @@ class audittrail_objects_proxy(object_proxy): assert model_id, _("'%s' Model does not exist..." %(model)) model = model_pool.browse(cr, uid, model_id) relational_table_log = args and args[-1] == 'child_relation_log' or False - if method in ('create'): + if method == 'create': fields_to_read = [] if relational_table_log: res_id = args[0] @@ -297,7 +297,7 @@ class audittrail_objects_proxy(object_proxy): cr.close() return res_id - elif method in ('read'): + elif method == 'read': res_ids = args[0] old_values = {} res = fct_src(db, uid_orig, model.model, method, *args) @@ -321,7 +321,7 @@ class audittrail_objects_proxy(object_proxy): cr.close() return res - elif method in ('unlink'): + elif method == 'unlink': res_ids = args[0] res = False old_values = {} From 3a581f8a27a1684218c3d98688f80b8cef5bfee9 Mon Sep 17 00:00:00 2001 From: "Amit Parmar (OpenERP)" Date: Wed, 7 Sep 2011 13:09:25 +0530 Subject: [PATCH 042/316] [IMP] Develop a purchase order import and export functionality bzr revid: aar@tinyerp.com-20110907073925-p7akjs01643z4m2b --- addons/email_template/email_template.py | 4 +- addons/purchase/__openerp__.py | 4 +- addons/purchase/edi_purchase_order.py | 7 +- addons/purchase/test/edi_purchase_order.yml | 7 +- addons/sale/__init__.py | 2 +- addons/sale/__openerp__.py | 22 +-- addons/sale/edi_sale_order.py | 187 ++++++++++++++++++++ addons/sale/edi_sale_order_data.xml | 76 ++++++++ addons/sale/test/edi_sale_order.yml | 51 ++++++ 9 files changed, 340 insertions(+), 20 deletions(-) create mode 100644 addons/sale/edi_sale_order.py create mode 100644 addons/sale/edi_sale_order_data.xml create mode 100644 addons/sale/test/edi_sale_order.yml diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index aabc211df11..57ba74a49d4 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -570,7 +570,8 @@ This is useful for CRM leads for example"), # determine name of sender, either it is specified in email_id or we # use the account name - email_id = from_account['email_id'].strip() + print "////////////////////////",from_account + email_id = from_account['email_id'] email_from = re.findall(r'([^ ,<@]+@[^> ,]+)', email_id)[0] if email_from != email_id: # we should keep it all, name is probably specified in the address @@ -670,6 +671,7 @@ This is useful for CRM leads for example"), if context is None: context = {} template = self.browse(cursor, user, template_id, context=context) + print ">>>>>>>>>>>><<<<<<<<<<<<<<<<",template if not template: raise Exception("The requested template could not be loaded") result = True diff --git a/addons/purchase/__openerp__.py b/addons/purchase/__openerp__.py index 21a9184cbb3..ae4eaa3c6e6 100644 --- a/addons/purchase/__openerp__.py +++ b/addons/purchase/__openerp__.py @@ -59,7 +59,7 @@ Dashboard for purchase management that includes: 'report/purchase_report_view.xml', 'board_purchase_view.xml', 'edi_purchase_order_data.xml', - + #'test/edi_purchase_order.yml', ], 'test': [ 'test/purchase_from_order.yml', @@ -68,7 +68,7 @@ Dashboard for purchase management that includes: 'purchase_unit_test.xml', 'test/procurement_buy.yml', 'test/purchase_report.yml', - 'test/edi_purchase_order.yml', + #'test/edi_purchase_order.yml', ], 'demo': ['purchase_demo.xml'], 'installable': True, diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 2d719300b8d..605e29621b1 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -104,8 +104,9 @@ class purchase_order(osv.osv, ir_edi.edi): #'company_logo': inv_comp.logo,#TODO #'paid': inv_comp.paid, #TODO }) + edi_doc['__model'] = 'sale.order' edi_doc_list.append(edi_doc) - print "??????????????????????",edi_doc_list + return edi_doc_list def edi_import(self, cr, uid, edi_document, context=None): @@ -169,7 +170,7 @@ class purchase_order(osv.osv, ir_edi.edi): for line in range(len(edi_document['order_line'])): product_qty = edi_document['order_line'][line]['product_uom_qty'] - edi_document['order_line'][line].update({'product_qty': product_qty}) + edi_document['order_line'][line].update({'product_qty': product_qty,'taxes_id':edi_document['order_line'][line]['tax_id']}) # all fields are converted for purchase order import so unnecessary fields are deleted delete_key = ['sequence','procurement_id','product_uom_qty','company_address','shop_id','create_date','picking_policy','order_policy','partner_order_id','partner_shipping_id','invoice_quantity','partner_invoice_id','price_subtotal','date_confirm'] @@ -180,7 +181,7 @@ class purchase_order(osv.osv, ir_edi.edi): for document in edi_document['order_line']: if document.has_key(key): del document[key] - + print "in the edi_purchase import",edi_document return super(purchase_order,self).edi_import(cr, uid, edi_document, context=context) purchase_order() diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml index e6ee0c76840..1fbc89db70a 100644 --- a/addons/purchase/test/edi_purchase_order.yml +++ b/addons/purchase/test/edi_purchase_order.yml @@ -10,16 +10,17 @@ I create one Purchase Order - !record {model: purchase.order, id: purchase_order_test}: - partner_id: res_partner_test22 + partner_id: res_partner_test20 partner_address_id: base.res_partner_address_11 location_id: stock.stock_location_3 pricelist_id: 1 order_line: - product_id: product.product_product_pc1 - product_uom_qty: 1.0 + product_qty: 1.0 product_uom: 1 price_unit: 150.0 name: 'basic pc' + date_planned: '2011-08-31' - I Open the sale order - @@ -40,7 +41,7 @@ assert tokens, 'Token is not generated' document = self.get_document(cr, uid, tokens[0]) document = json.loads(document) - document[0]["__model"] = "purchase.order" + document[0]["__model"] = "sale.order" document = json.dumps(document) a = self.import_edi(cr, uid, edi_document = document) diff --git a/addons/sale/__init__.py b/addons/sale/__init__.py index 3c7af56e808..6361fea3a0b 100644 --- a/addons/sale/__init__.py +++ b/addons/sale/__init__.py @@ -29,5 +29,5 @@ import sale_installer import wizard import report import company - +import edi_sale_order # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index c983edc881e..fa139377b40 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -85,20 +85,22 @@ Dashboard for Sales Manager that includes: 'stock_view.xml', 'board_sale_view.xml', 'process/sale_process.xml', + 'edi_sale_order_data.xml', ], 'demo_xml': ['sale_demo.xml'], 'test': [ 'test/data_test.yml', - 'test/manual_order_policy.yml', - 'test/prepaid_order_policy.yml', - 'test/picking_order_policy.yml', - 'test/postpaid_order_policy.yml', - 'test/advance_invoice.yml', - 'test/so_make_line_invoice.yml', - 'test/sale_procurement.yml', - 'test/invoice_on_ordered_qty.yml', - 'test/invoice_on_shipped_qty.yml', - 'test/sale_report.yml', + #'test/manual_order_policy.yml', + #'test/prepaid_order_policy.yml', + #'test/picking_order_policy.yml', + #'test/postpaid_order_policy.yml', + #'test/advance_invoice.yml', + #'test/so_make_line_invoice.yml', + #'test/sale_procurement.yml', + #'test/invoice_on_ordered_qty.yml', + #'test/invoice_on_shipped_qty.yml', + #'test/sale_report.yml', + #'test/edi_sale_order.yml', ], 'installable': True, 'active': False, diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py new file mode 100644 index 00000000000..d33c4664992 --- /dev/null +++ b/addons/sale/edi_sale_order.py @@ -0,0 +1,187 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +from osv import fields, osv, orm +from base.ir import ir_edi +from tools.translate import _ +from datetime import date +class sale_order(osv.osv, ir_edi.edi): + _inherit = 'sale.order' + + def edi_export(self, cr, uid, records, edi_struct=None, context=None): + """Exports a Sale order""" + edi_struct = { + 'name': True, + 'shop_id': True, + 'origin': True, + 'amount_total': True, + 'date_order': True, + 'date_confirm': True, + 'partner_id': True, + 'partner_invoice_id': True, + 'pricelist_id': True, + 'company_id': True, + 'amount_tax': True, + 'amount_total': True, + 'amount_untaxed': True, + 'order_line': { + 'name': True, + 'product_id': True, + 'procurement_id': True, + 'price_unit': True, + 'price_subtotal': True, + 'tax_id': True, + 'product_uom': True, + 'product_uom_qty': True, + 'product_uos': True, + + }, + 'shipped': True, + } + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + company_address_dict = { + 'street': True, + 'street2': True, + 'zip': True, + 'city': True, + 'state_id': True, + 'country_id': True, + 'email': True, + 'phone': True, + + } + edi_doc_list = [] + for order in records: + # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. + edi_doc = super(sale_order,self).edi_export(cr, uid, [order], edi_struct, context) + if not edi_doc: + continue + edi_doc = edi_doc[0] + + # Add company info and address + res = partner_pool.address_get(cr, uid, [order.shop_id.company_id.partner_id.id], ['contact', 'order']) + contact_addr_id = res['contact'] + invoice_addr_id = res['order'] + + address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) + edi_company_address_dict = {} + for key, value in company_address_dict.items(): + if not value: + continue + address_rec = getattr(address, key) + if not address_rec: + continue + if key.endswith('_id'): + address_rec = self.edi_m2o(cr, uid, address_rec, context=context) + + edi_company_address_dict[key] = address_rec + + edi_doc.update({ + 'company_address': edi_company_address_dict, + #'company_logo': inv_comp.logo,#TODO + #'paid': inv_comp.paid, #TODO + }) + edi_doc['__model'] = 'purchase.order' + edi_doc_list.append(edi_doc) + return edi_doc_list + + def edi_import(self, cr, uid, edi_document, context=None): + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') + model_data_pool = self.pool.get('ir.model.data') + product_pool = self.pool.get('product.product') + product_categ_pool = self.pool.get('product.category') + company_pool = self.pool.get('res.company') + country_pool = self.pool.get('res.country') + state_pool = self.pool.get('res.country.state') + + tax_id = [] + account_id = [] + partner_id = None + company_id = None + if context is None: + context = {} + + # import company as a new partner, if type==in then supplier=1, else customer=1 + # partner_id field is modified to point to the new partner + # company_address data used to add address to new partner + edi_company_address = edi_document['company_address'] + edi_partner_id = edi_document['partner_id'] + company_name = edi_document['company_id'][1] + state_id = edi_company_address.get('state_id', False) + state_name = state_id and state_id[1] + country_id = edi_company_address.get('country_id', False) + country_name = country_id and country_id[1] + + country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False + state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, + values={'country_id': country_id, 'code': state_name}, context=context) or False + address_value = { + 'street': edi_company_address.get('street', False), + 'street2': edi_company_address.get('street2', False), + 'zip': edi_company_address.get('zip', False), + 'city': edi_company_address.get('city', False), + 'state_id': state_id, + 'country_id': country_id, + 'email': edi_company_address.get('email', False), + 'phone': edi_company_address.get('phone', False), + + } + + partner_value = {'name': company_name} + partner_value.update({'customer': True, 'supplier': False}) + + partner_id = partner_pool.create(cr, uid, partner_value, context=context) + address_value.update({'partner_id': partner_id}) + address_id = partner_address_pool.create(cr, uid, address_value, context=context) + partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) + partner_address_id = self.edi_m2o(cr, uid, partner_address, context=context) + partner = partner_pool.browse(cr, uid, partner_id, context=context) + edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) + edi_document.update({ + 'partner_invoice_id': partner_address_id, + 'partner_order_id': partner_address_id, + 'partner_shipping_id': partner_address_id, + #'product_uom_qty': edi_document['order_line'][0]['product_qty'], + 'delay': 10, + }) + + # all fields are converted for sale order import so unnecessary fields are deleted + for i in range(len(edi_document['order_line'])): + edi_document['order_line'][i].update({'tax_id':edi_document['order_line'][i]['taxes_id']}) + delete_key = ['date_planned','product_qty','date_approve','validator','location_id','partner_address_id','company_address','company_id','warehouse_id','taxes_id'] + for key in delete_key: + if edi_document.has_key(key): + del edi_document[key] + else: + for document in edi_document['order_line']: + if document.has_key(key): + del document[key] + return super(sale_order,self).edi_import(cr, uid, edi_document, context=context) + +sale_order() + +class sale_order_line(osv.osv, ir_edi.edi): + _inherit='sale.order.line' + +sale_order_line() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml new file mode 100644 index 00000000000..a9e25bd2562 --- /dev/null +++ b/addons/sale/edi_sale_order_data.xml @@ -0,0 +1,76 @@ + + + + + + context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, + uid, + self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], + [object.id], + context=context) + + code + ir.actions.server + + True + EDI Document - Sale Order + + + + + + + + + + + + ${object.company_id.name} - Sale Order ${object.name} + ${object.partner_invoice_id.email} + + True + +<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); "> + +<p> Hello ${object.partner_invoice_id.name and ' ' or ''},</p> +<p> You can click on the following link to preview, print and pay invoice: <br/> + <a href="${object._context.get('edi_web_url_view')}">${object._context.get('edi_web_url_view')} </a> +</p> + + +<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Confirm date: ${object.date_confirm or 'n/a'}<br /> Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></p> + +${object.company_id.paypal_account and "<p>It is possible to pay with Paypal: <br/> <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s\"><img src=\"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif\" style=\"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;\"/></a> </p>"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} + +<p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></div> <div> </div> </div> </div> <p> </p> + + +Hello ${object.partner_invoice_id.name and ' ' or ''}, + +You can click on the following link to preview, print and pay invoice: + + ${object._context.get('edi_web_url_view') or 'n/a'} + +Order Number: *${object.name}* +Amount: *${object.amount_total}* +Confirm date: ${object.date_confirm or 'n/a'} +Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} + +${object.company_id.paypal_account and "It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} + +If you have any question, do not hesitate to reply directly to this e-mail. + +Thank you for choosing our service! + +-- +${object.company_id.name} +Contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} + + mako + Mail Template of Sale Order For EDI Document + sale.order + ${object.user_id.user_email or ''} + + + diff --git a/addons/sale/test/edi_sale_order.yml b/addons/sale/test/edi_sale_order.yml new file mode 100644 index 00000000000..8ad461ea476 --- /dev/null +++ b/addons/sale/test/edi_sale_order.yml @@ -0,0 +1,51 @@ +- + I create a partner which is a my customer ====================================== +- + !record {model: res.partner, id: res_partner_test22}: + name: Junjun wala + supplier: False + customer: True + opt_out: False +- + I create one Sale Order ======================================= +- + !record {model: sale.order, id: sale_order_test}: + partner_id: res_partner_test22 + partner_invoice_id: base.res_partner_address_3 + partner_order_id: base.res_partner_address_3 + partner_shipping_id: base.res_partner_address_3 + pricelist_id: 1 + order_line: + - product_id: product.product_product_pc1 + product_uom_qty: 1.0 + product_uom: 1 + price_unit: 150.0 + name: 'basic pc' +- + I Open the sale order ============================ +- + !python {model: sale.order}: | + + orders = self.browse(cr, uid, ref("sale_order_test")) + import netsvc + wf_service = netsvc.LocalService("workflow") + wf_service.trg_validate(uid, 'sale.order',orders.id,'order_confirm', cr) + +- + I Tesing of EDI functionality. First I export Sale Order from my company than import that Order into customer company +- + !python {model: ir.edi.document}: | + import json + invoice_pool = self.pool.get('sale.order') + orders = invoice_pool.browse(cr, uid, ref("sale_order_test")) + + tokens = self.export_edi(cr, uid, [orders]) + assert tokens, 'Token is not generated' + document = self.get_document(cr, uid, tokens[0]) + document = json.loads(document) + document[0]["__model"] = "purchase.order" + document = json.dumps(document) + a = self.import_edi(cr, uid, edi_document = document) + assert a, 'Invoice is not imported' + + From 044e4f4c1a6c3be56d8efc581bb4520f6fedf251 Mon Sep 17 00:00:00 2001 From: "Naresh (OpenERP)" Date: Wed, 7 Sep 2011 18:08:13 +0530 Subject: [PATCH 043/316] [IMP/REF]:allowed entires to be logged when doing different actions/workflow/on_change/write etc...and removed and refactored the code bzr revid: nch@tinyerp.com-20110907123813-4thzx4y3e9vic7uq --- addons/audittrail/audittrail.py | 231 ++++++++++++++++---------------- 1 file changed, 114 insertions(+), 117 deletions(-) diff --git a/addons/audittrail/audittrail.py b/addons/audittrail/audittrail.py index 244f26fba3f..579ba005ba3 100644 --- a/addons/audittrail/audittrail.py +++ b/addons/audittrail/audittrail.py @@ -231,7 +231,7 @@ class audittrail_objects_proxy(object_proxy): cr.commit() return True - def get_x2m_m2o_values(self, cr, db, uid, pool, resource_pool, method, field, value, recursive=True): + def get_value_text(self, cr, db, uid, pool, resource_pool, method, field, value, recursive=True): field_obj = (resource_pool._all_columns.get(field)).column if field_obj._type in ('one2many','many2many'): if recursive: @@ -242,6 +242,27 @@ class audittrail_objects_proxy(object_proxy): return value and value[1] or value return False + def start_log_process(self, cr, db, user_id, model, method, resource_data, pool, resource_pool): + key1 = '%s_value'%(method == 'create' and 'new' or 'old') + key2 = '%s_value_text'%(method == 'create' and 'new' or 'old') + uid = 1 + vals = { 'method': method, 'object_id': model.id,'user_id': user_id} + for resource, fields in resource_data.iteritems(): + vals.update({'res_id': resource}) + log_id = pool.get('audittrail.log').create(cr, uid, vals) + lines = [] + for field_key, value in fields.iteritems(): + if field_key in ('__last_update', 'id'):continue + ret_val = self.get_value_text(cr, db, uid, pool, resource_pool, method, field_key, value, method != 'read') + line = { + 'name': field_key, + key1: value, + key2: ret_val and ret_val or value + } + lines.append(line) + self.create_log_line(cr, uid, log_id, model, lines) + return True + def log_fct(self, db, uid, model, method, fct_src, *args): """ Logging function: This function is performs logging operations according to method @@ -259,14 +280,12 @@ class audittrail_objects_proxy(object_proxy): cr = pooler.get_db(db).cursor() resource_pool = pool.get(model) log_pool = pool.get('audittrail.log') - model_pool = pool.get('ir.model') - - model_ids = model_pool.search(cr, uid, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - assert model_id, _("'%s' Model does not exist..." %(model)) - model = model_pool.browse(cr, uid, model_id) + model = self.check_rule_subscription(cr, uid, pool, model, False) + assert model, _("'%s' Model does not exist..." %(model)) + relational_table_log = args and args[-1] == 'child_relation_log' or False if method == 'create': + resource_data = {} fields_to_read = [] if relational_table_log: res_id = args[0] @@ -274,77 +293,29 @@ class audittrail_objects_proxy(object_proxy): res_id = fct_src(db, uid_orig, model.model, method, *args) cr.commit() fields_to_read = args[0].keys() - resource = resource_pool.read(cr, uid, res_id, fields_to_read) - if not isinstance(resource, list): - resource = [resource] - vals = { 'method': method, 'object_id': model.id,'user_id': uid_orig} - for resource_data in resource: - vals.update({'res_id': resource_data['id']}) - del resource_data['id'] - log_id = log_pool.create(cr, uid, vals) - lines = [] - for field in resource_data: - if field in ('__last_update', 'id'):continue - ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource_data[field]) - line = { - 'name': field, - 'new_value': resource_data[field], - 'new_value_text': ret_val and ret_val or resource_data[field] - } - lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) - cr.commit() + if res_id: + resource = resource_pool.read(cr, uid, res_id, fields_to_read) + if not isinstance(resource,list): + resource = [resource] + map(lambda x: resource_data.setdefault(x['id'], x), resource) + self.start_log_process(cr, db, uid_orig, model, method, resource_data, pool, resource_pool) + cr.commit() cr.close() return res_id - elif method == 'read': + elif method in('read', 'unlink'): res_ids = args[0] old_values = {} - res = fct_src(db, uid_orig, model.model, method, *args) - map(lambda x:old_values.setdefault(x['id'], x), res) - vals = {'method': method,'object_id': model.id,'user_id': uid_orig} - for res_id in old_values: - vals.update({'res_id': res_id}) - log_id = log_pool.create(cr, uid, vals) - lines = [] - for field in old_values[res_id]: - if field in ('__last_update', 'id'):continue - ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, old_values[res_id][field], False) - line = { - 'name': field, - 'old_value': old_values[res_id][field], - 'old_value_text': ret_val and ret_val or old_values[res_id][field] - } - lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) - cr.commit() - cr.close() - return res - - elif method == 'unlink': - res_ids = args[0] - res = False - old_values = {} - for res_id in res_ids: - old_values[res_id] = resource_pool.read(cr, uid, res_id) - vals = {'method': method,'object_id': model.id,'user_id': uid_orig} - for res_id in res_ids: - vals.update({'res_id': res_id}) - log_id = log_pool.create(cr, uid, vals) - lines = [] - for field in old_values[res_id]: - if field in ('__last_update', 'id'):continue - ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, old_values[res_id][field]) - line = { - 'name': field, - 'old_value': old_values[res_id][field], - 'old_value_text': ret_val and ret_val or old_values[res_id][field] - } - lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) - if not relational_table_log: + if method == 'read': res = fct_src(db, uid_orig, model.model, method, *args) - cr.commit() + map(lambda x: old_values.setdefault(x['id'], x), res) + else: + res = resource_pool.read(cr, uid, res_ids) + map(lambda x:old_values.setdefault(x['id'], x), res) + self.start_log_process(cr, db, uid_orig, model, method, old_values, pool, resource_pool) + if not relational_table_log and method == 'unlink': + res = fct_src(db, uid_orig, model.model, method, *args) + cr.commit() cr.close() return res else: @@ -359,47 +330,79 @@ class audittrail_objects_proxy(object_proxy): if isinstance(res_ids, (long, int)): res_ids = [res_ids] if res_ids: - resource_data = resource_pool.read(cr, uid, res_ids) - for resource in resource_data: - resource_id = resource['id'] - del resource['id'] - old_values_text = {} - old_value = {} - for field in resource.keys(): - if field in ('__last_update', 'id'):continue - ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource[field]) - old_value[field] = resource[field] - old_values_text[field] = ret_val and ret_val or resource[field] - old_values[resource_id] = {'text':old_values_text, 'value': old_value} - if not relational_table_log: - res = fct_src(db, uid_orig, model.model, method, *args) - cr.commit() + x2m_old_values = {} + old_values = {} + def inline_process_old_data(res_ids, model, model_id=False): + resource_pool = pool.get(model) + resource_data = resource_pool.read(cr, uid, res_ids) + _old_values = {} + for resource in resource_data: + _old_values_text = {} + _old_value = {} + resource_id = resource['id'] + for field in resource.keys(): + if field in ('__last_update', 'id'):continue + field_obj = (resource_pool._all_columns.get(field)).column + if field_obj._type in ('one2many','many2many'): + x2m_rule_ids, x2m_model = self.check_rule_subscription(cr, uid, pool, field_obj._obj) + if x2m_rule_ids: + x2m_old_values.update(inline_process_old_data(resource[field], field_obj._obj, x2m_model)) + ret_val = self.get_value_text(cr, db, uid, pool, resource_pool, method, field, resource[field], False) + _old_value[field] = resource[field] + _old_values_text[field] = ret_val and ret_val or resource[field] + _old_values[resource_id] = {'text':_old_values_text, 'value': _old_value} + if model_id: + _old_values[resource_id].update({'model_id':model_id}) + return _old_values + old_values.update(inline_process_old_data(res_ids, model.model)) + res = fct_src(db, uid_orig, model.model, method, *args) + cr.commit() if res_ids: - resource_data = resource_pool.read(cr, uid, res_ids) - vals = {'method': method,'object_id': model.id,'user_id': uid_orig } - for resource in resource_data: - resource_id = resource['id'] - del resource['id'] - vals.update({'res_id': resource_id}) - log_id = log_pool.create(cr, uid, vals) - lines = [] - for field in resource.keys(): - if field in ('__last_update', 'id'):continue - ret_val = self.get_x2m_m2o_values(cr, db, uid, pool, resource_pool, method, field, resource[field], False) - line = { - 'name': field, - 'new_value': resource[field], - 'old_value': old_values[resource_id]['value'][field], - 'new_value_text': ret_val and ret_val or resource[field], - 'old_value_text': old_values[resource_id]['text'][field] - } - lines.append(line) - self.create_log_line(cr, uid, log_id, model, lines) + def inline_process_new_data(res_ids, model, dict_to_use={}): + resource_pool = pool.get(model.model) + resource_data = resource_pool.read(cr, uid, res_ids) + vals = {'method': method,'object_id': model.id,'user_id': uid_orig } + for resource in resource_data: + resource_id = resource['id'] + vals.update({'res_id': resource_id}) + log_id = log_pool.create(cr, uid, vals) + lines = [] + for field in resource.keys(): + if field in ('__last_update', 'id'):continue + field_obj = (resource_pool._all_columns.get(field)).column + if field_obj._type in ('one2many','many2many'): + x2m_rule_ids, x2m_model = self.check_rule_subscription(cr, uid, pool, field_obj._obj) + if x2m_rule_ids: + inline_process_new_data(resource[field], x2m_model, x2m_old_values) + ret_val = self.get_value_text(cr, db, uid, pool, resource_pool, method, field, resource[field], False) + line = { + 'name': field, + 'new_value': resource[field], + 'old_value': resource_id in dict_to_use and dict_to_use[resource_id]['value'].get(field), + 'new_value_text': ret_val and ret_val or resource[field], + 'old_value_text': resource_id in dict_to_use and dict_to_use[resource_id]['text'].get(field) + } + lines.append(line) + self.create_log_line(cr, uid, log_id, model, lines) + return True + inline_process_new_data(res_ids, model, old_values) cr.commit() cr.close() return res return True - + + def check_rule_subscription(self, cr, uid, pool, model, rule_check=True): + ''' + Test if the model has been subscribed to the audit rule + if yes then return the rule_ids also return the model browse_record object. + ''' + model_ids = pool.get('ir.model').search(cr, uid, [('model', '=', model)]) + model_obj = model_ids and model_ids[0] and pool.get('ir.model').browse(cr, uid, model_ids[0]) or False + if rule_check: + rule_ids = pool.get('audittrail.rule').search(cr, uid, [('object_id', '=', model_obj.id), ('state', '=', 'subscribed')]) + return rule_ids, model_obj + return model_obj + def audit_log_call(self, db, uid, model, method, action_type, *args, **argv): """ Overrides Object Proxy execute method @@ -414,8 +417,6 @@ class audittrail_objects_proxy(object_proxy): uid = 1 pool = pooler.get_pool(db) logged_uids = [] - model_pool = pool.get('ir.model') - rule_pool = pool.get('audittrail.rule') cr = pooler.get_db(db).cursor() cr.autocommit(True) if action_type == 'execute': @@ -426,14 +427,10 @@ class audittrail_objects_proxy(object_proxy): else: fct_src = super(audittrail_objects_proxy, self).exec_workflow try: - model_ids = model_pool.search(cr, uid, [('model', '=', model)]) - model_id = model_ids and model_ids[0] or False - if not ('audittrail.rule' in pool.obj_list()) or not model_id: + rule_ids, model_obj = self.check_rule_subscription(cr, uid, pool, model) + if not ('audittrail.rule' in pool.obj_list() and model_obj and rule_ids): return fct_src(db, uid_orig, model, method, *args, **argv) - rule_ids = rule_pool.search(cr, uid, [('object_id', '=', model_id), ('state', '=', 'subscribed')]) - if not rule_ids: - return fct_src(db, uid_orig, model, method, *args, **argv) - for model_rule in rule_pool.browse(cr, uid, rule_ids): + for model_rule in pool.get('audittrail.rule').browse(cr, uid, rule_ids): logged_uids += map(lambda x:x.id, model_rule.user_id) if not logged_uids or uid in logged_uids: if action_type == 'execute': From 5236ef43f183ae40f53bb432b184be81a151b707 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 8 Sep 2011 15:13:29 +0530 Subject: [PATCH 044/316] [IMP] accout.edi_invoice: to split edi_import() in smaller methods for importing the different parts bzr revid: hmo@tinyerp.com-20110908094329-14cutn414nbpvgvr --- addons/account/edi_invoice.py | 147 +++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 63 deletions(-) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index 179f2eb7234..cbcddb2430d 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -113,50 +113,57 @@ class account_invoice(osv.osv, ir_edi.edi): edi_doc_list.append(edi_doc) return edi_doc_list - def edi_import(self, cr, uid, edi_document, context=None): - """ During import, invoices will import the company that is provided in the invoice as - a new partner (e.g. supplier company for a customer invoice will be come a supplier - record for the new invoice. - Summary of tasks that need to be done: - - import company as a new partner, if type==in then supplier=1, else customer=1 - - partner_id field is modified to point to the new partner - - company_address data used to add address to new partner - - change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund' - - reference: should contain the value of the 'internal_number' - - reference_type: 'none' - - internal number: reset to False, auto-generated - - journal_id: should be selected based on type: simply put the 'type' - in the context when calling create(), will be selected correctly - - payment_term: if set, create a default one based on name... - - 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 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. - """ - - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - model_data_pool = self.pool.get('ir.model.data') - product_pool = self.pool.get('product.product') - product_categ_pool = self.pool.get('product.category') - company_pool = self.pool.get('res.company') - country_pool = self.pool.get('res.country') - state_pool = self.pool.get('res.country.state') - account_journal_pool = self.pool.get('account.journal') - invoice_line_pool = self.pool.get('account.invoice.line') - account_pool = self.pool.get('account.account') - tax_id = [] - account_id = [] - partner_id = None - company_id = None + 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 + account_pool = self.pool.get('account.account') + account_ids = account_pool.search(cr, uid, [('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]) + tax_account = False + if account_ids: + 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): + 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'): + invoice_account = partner.property_account_receivable + else: + invoice_account = partner.property_account_payable + return invoice_account + + def get_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 + else: + account = product.product_tmpl_id.property_account_expense + if not account: + account = product.categ_id.property_account_expense_categ + return account + + def edi_import_company(self, cr, uid, edi_document, context=None): # import company as a new partner, if type==in then supplier=1, else customer=1 # partner_id field is modified to point to the new partner # company_address data used to add address to new partner + + partner_pool = self.pool.get('res.partner') + partner_address_pool = self.pool.get('res.partner.address') edi_company_address = edi_document['company_address'] edi_partner_id = edi_document['partner_id'] company_name = edi_document['company_id'][1] @@ -198,15 +205,43 @@ class account_invoice(osv.osv, ir_edi.edi): partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) edi_document['address_invoice_id'] = self.edi_m2o(cr, uid, partner_address, context=context) + return partner.id + + def edi_import(self, cr, uid, edi_document, context=None): + """ During import, invoices will import the company that is provided in the invoice as + a new partner (e.g. supplier company for a customer invoice will be come a supplier + record for the new invoice. + Summary of tasks that need to be done: + - import company as a new partner, if type==in then supplier=1, else customer=1 + - partner_id field is modified to point to the new partner + - company_address data used to add address to new partner + - change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund' + - reference: should contain the value of the 'internal_number' + - reference_type: 'none' + - internal number: reset to False, auto-generated + - journal_id: should be selected based on type: simply put the 'type' + in the context when calling create(), will be selected correctly + - payment_term: if set, create a default one based on name... + - 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 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. + """ + if context is None: + context = {} + + #import company as a new partner + partner_id = self.edi_import_company(cr, uid, edi_document, context=context) + # 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 # Set Account - if invoice_type in ('out_invoice', 'out_refund'): - invoice_account = partner.property_account_receivable - else: - invoice_account = partner.property_account_payable + invoice_account = self.get_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' @@ -222,13 +257,9 @@ class account_invoice(osv.osv, ir_edi.edi): del edi_document['company_id'] # journal_id: should be selected based on type: simply put the 'type' in the context when calling create(), will be selected correctly - 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) + 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 + # 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) @@ -236,16 +267,7 @@ class account_invoice(osv.osv, ir_edi.edi): 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) - product = product_pool.browse(cr, uid, product_id, context=context) - - 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 - else: - account = product.product_tmpl_id.property_account_expense - if not account: - account = product.categ_id.property_account_expense_categ + account = self.get_product_account(cr, uid, product_id, invoice_type, context=context) # TODO: add effect of fiscal position # 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 @@ -253,10 +275,9 @@ class account_invoice(osv.osv, ir_edi.edi): # 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. for edi_tax_line in edi_document.get('tax_line', []): - account_ids = account_pool.search(cr, uid, [('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]) - if account_ids: - tax_account = account_pool.browse(cr, uid, account_ids[0]) - edi_tax_line['account_id'] = self.edi_m2o(cr, uid, tax_account, context=context) #TODO should select account of output VAT for Customer Invoice and Input VAT for Supplier Invoice + 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['manual'] = True # TODO :=> payment_term: if set, create a default one based on name... From 4dc536c8ce05b870e332acb01d8f9aab55184256 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Tue, 13 Sep 2011 18:29:23 +0530 Subject: [PATCH 045/316] [IMP] account: improve edi import of invoice to split in different stuff [IMP] sale: edi import process and correct EDI struct on exort [IMP] purchase: edi import process and correct EDI struct on export bzr revid: hmo@tinyerp.com-20110913125923-2gbhgd1vzyd2qrwy --- addons/account/edi_invoice.py | 101 ++------- addons/account/test/test_edi_invoice.yml | 62 +++++- addons/purchase/edi_purchase_order.py | 231 ++++++++------------ addons/purchase/edi_purchase_order_data.xml | 4 +- addons/purchase/test/edi_purchase_order.yml | 60 ++++- addons/sale/__openerp__.py | 3 +- addons/sale/edi_sale_order.py | 223 ++++++++----------- addons/sale/test/data_test.yml | 1 + addons/sale/test/edi_sale_order.yml | 55 ++++- 9 files changed, 362 insertions(+), 378 deletions(-) diff --git a/addons/account/edi_invoice.py b/addons/account/edi_invoice.py index cbcddb2430d..db09e7ab6aa 100644 --- a/addons/account/edi_invoice.py +++ b/addons/account/edi_invoice.py @@ -66,20 +66,9 @@ class account_invoice(osv.osv, ir_edi.edi): 'base_amount': True, 'tax_amount': True, }, + #'paid': True, } - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - company_address_dict = { - 'street': True, - 'street2': True, - 'zip': True, - 'city': True, - 'state_id': True, - 'country_id': True, - 'email': True, - 'phone': True, - - } + company_pool = 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. @@ -89,26 +78,10 @@ class account_invoice(osv.osv, ir_edi.edi): edi_doc = edi_doc[0] # Add company info and address - res = partner_pool.address_get(cr, uid, [invoice.company_id.partner_id.id], ['contact', 'invoice']) - contact_addr_id = res['contact'] - invoice_addr_id = res['invoice'] - - address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) - edi_company_address_dict = {} - for key, value in company_address_dict.items(): - if not value: - continue - address_rec = getattr(address, key) - if not address_rec: - continue - if key.endswith('_id'): - address_rec = self.edi_m2o(cr, uid, address_rec, context=context) - edi_company_address_dict[key] = address_rec - + edi_company_document = company_pool.edi_export_address(cr, uid, [invoice.company_id], context=context)[invoice.company_id.id] edi_doc.update({ - 'company_address': edi_company_address_dict, - #'company_logo': inv_comp.logo,#TODO - #'paid': inv_comp.paid, #TODO + 'company_address': edi_company_document['company_address'], + #'company_logo': edi_company_document['company_logo'],#TODO }) edi_doc_list.append(edi_doc) return edi_doc_list @@ -158,54 +131,30 @@ class account_invoice(osv.osv, ir_edi.edi): return account def edi_import_company(self, cr, uid, edi_document, context=None): - # import company as a new partner, if type==in then supplier=1, else customer=1 - # partner_id field is modified to point to the new partner - # company_address data used to add address to new partner - - partner_pool = self.pool.get('res.partner') partner_address_pool = self.pool.get('res.partner.address') - edi_company_address = edi_document['company_address'] - edi_partner_id = edi_document['partner_id'] - company_name = edi_document['company_id'][1] + partner_pool = self.pool.get('res.partner') + company_pool = self.pool.get('res.company') + + # 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 invoice_type = edi_document['type'] - state_id = edi_company_address.get('state_id', False) - state_name = state_id and state_id[1] - country_id = edi_company_address.get('country_id', False) - country_name = country_id and country_id[1] - - country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False - state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, - values={'country_id': country_id, 'code': state_name}, context=context) or False - address_value = { - 'street': edi_company_address.get('street', False), - 'street2': edi_company_address.get('street2', False), - 'zip': edi_company_address.get('zip', False), - 'city': edi_company_address.get('city', False), - 'state_id': state_id, - 'country_id': country_id, - 'email': edi_company_address.get('email', False), - 'phone': edi_company_address.get('phone', False), - - } - - - partner_value = {'name': company_name} + partner_value = {} if invoice_type in ('out_invoice', 'in_refund'): - partner_value.update({'customer': True, 'supplier': False}) + partner_value.update({'customer': True}) if invoice_type in ('in_invoice', 'out_refund'): - partner_value.update({'customer': False, 'supplier': True}) - - partner_id = partner_pool.create(cr, uid, partner_value, context=context) - address_value.update({'partner_id': partner_id}) - address_id = partner_address_pool.create(cr, uid, address_value, context=context) + partner_value.update({'supplier': True}) + partner_id = company_pool.edi_import_as_partner(cr, uid, edi_document, values=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) - edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, 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) - - return partner.id + del edi_document['company_id'] + return partner_id + def edi_import(self, cr, uid, edi_document, context=None): """ During import, invoices will import the company that is provided in the invoice as @@ -251,10 +200,7 @@ class account_invoice(osv.osv, ir_edi.edi): # internal number: reset to False, auto-generated edi_document['internal_number'] = False - - # company should set by default so delete company data from edi Document - del edi_document['company_address'] - del edi_document['company_id'] + # 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) @@ -281,7 +227,6 @@ class account_invoice(osv.osv, ir_edi.edi): 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() @@ -294,3 +239,5 @@ class account_invoice_tax(osv.osv, ir_edi.edi): _inherit = "account.invoice.tax" account_invoice_tax() + + diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index 0a03c3ca9dc..e01e6aaa712 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -56,7 +56,7 @@ wf_service.trg_validate(uid, 'account.invoice',invoices.id,'invoice_open', cr) - - I Tesing of EDI functionality. First I export customer invoice from my company than import that invoice into customer company + 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') @@ -64,9 +64,60 @@ tokens = self.export_edi(cr, uid, [invoice]) assert tokens, 'Token is not generated' - document = self.get_document(cr, uid, tokens[0]) - a = self.import_edi(cr, uid, edi_document = document) - assert a, 'Invoice is not imported' +- + I import of EDI document of custmer invoice +- + !python {model: ir.edi.document}: | + invoice_pool = self.pool.get('account.invoice') + edi_document = { + "internal_number": "SAJ/2011/002", + "company_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", + "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, + "date_invoice": "2011-06-22", + "amount_untaxed": 10.0, + "name": "selling product", + "__model": "account.invoice", + "__last_update": False, + "tax_line": [{ + "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, + "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"], + "quantity": 1.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 - @@ -75,8 +126,7 @@ invoice_old = self.browse(cr, uid, ref("customer_invoice_test")) new_partner_id = self.pool.get('res.partner').name_search(cr, uid, invoice_old.company_id.name) assert new_partner_id, 'Partner is not created of Supplier' - - ids = self.search(cr, uid, [('partner_id','=',new_partner_id[0][0]),('reference','=',invoice_old.internal_number)]) + 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]) assert invoice_new.reference == invoice_old.internal_number, "internal number is not stored in reference" diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 605e29621b1..cb19f57c103 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -22,58 +22,48 @@ from osv import fields, osv, orm from base.ir import ir_edi from tools.translate import _ -from datetime import date +from datetime import date, datetime, timedelta class purchase_order(osv.osv, ir_edi.edi): _inherit = 'purchase.order' def edi_export(self, cr, uid, records, edi_struct=None, context=None): - """Exports a supplier or customer invoice""" + """Exports a purchase order""" edi_struct = { + 'company_id': True, # -> to be changed into partner + 'name': True, + + 'date_order': True, + 'partner_id': True, + 'partner_address_id': True, #only one address needed + #SO: 'partner_order_id' + #PO: 'partner_address_id' + + 'pricelist_id': True, + 'notes': True, + #SO: 'note' + #PO: 'notes' + + 'amount_total': True, + 'amount_tax': True, + 'amount_untaxed': True, + 'order_line': { 'name': True, - 'origin': True, - 'date_order': True, - 'date_approve': True, - 'partner_id': True, - 'partner_address_id': True, - 'dest_address_id': True, - 'warehouse_id': True, - 'location_id': True, - 'pricelist_id': True, - 'validator' : True, - 'amount_tax': True, - 'amount_total': True, - 'amount_untaxed': True, - 'order_line': { - 'name': True, - 'product_qty': True, - 'date_planned': True, - 'taxes_id': True, - 'product_uom': True, - 'product_id': True, - 'move_dest_id': True, - 'price_unit': True, - 'order_id': True, - 'invoiced': True, - 'price_subtotal': True, - }, - 'invoice_ids': True, - 'shipped': True, - 'company_id': True, - } - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - company_address_dict = { - 'street': True, - 'street2': True, - 'zip': True, - 'city': True, - 'state_id': True, - 'country_id': True, - 'email': True, - 'phone': True, - + 'date_planned': True, + #SO: 'delay' : 'date_approve' - 'date_planned' + #PO: 'date_planned': 'date_approve' + 'delay' + + 'product_id': True, + 'product_uom': True, + 'price_unit': True, + 'product_qty': True, + #SO: 'product_uom_qty' + #PO: 'product_qty' + + 'notes': True, + } } + company_pool = self.pool.get('res.company') edi_doc_list = [] for order in records: # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. @@ -83,107 +73,80 @@ class purchase_order(osv.osv, ir_edi.edi): edi_doc = edi_doc[0] # Add company info and address - res = partner_pool.address_get(cr, uid, [order.company_id.partner_id.id], ['contact', 'order']) - contact_addr_id = res['contact'] - invoice_addr_id = res['order'] - - address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) - edi_company_address_dict = {} - for key, value in company_address_dict.items(): - if not value: - continue - address_rec = getattr(address, key) - if not address_rec: - continue - if key.endswith('_id'): - address_rec = self.edi_m2o(cr, uid, address_rec, context=context) - edi_company_address_dict[key] = address_rec - + edi_company_document = company_pool.edi_export_address(cr, uid, [order.company_id], context=context)[order.company_id.id] edi_doc.update({ - 'company_address': edi_company_address_dict, - #'company_logo': inv_comp.logo,#TODO - #'paid': inv_comp.paid, #TODO + 'company_address': edi_company_document['company_address'], + #'company_logo': edi_company_document['company_logo'],#TODO }) - edi_doc['__model'] = 'sale.order' edi_doc_list.append(edi_doc) - return edi_doc_list - def edi_import(self, cr, uid, edi_document, context=None): - - partner_pool = self.pool.get('res.partner') + def edi_import_company(self, cr, uid, edi_document, context=None): partner_address_pool = self.pool.get('res.partner.address') - model_data_pool = self.pool.get('ir.model.data') - product_pool = self.pool.get('product.product') - product_categ_pool = self.pool.get('product.category') + partner_pool = self.pool.get('res.partner') company_pool = self.pool.get('res.company') - country_pool = self.pool.get('res.country') - state_pool = self.pool.get('res.country.state') - account_journal_pool = self.pool.get('account.journal') - invoice_line_pool = self.pool.get('account.invoice.line') - account_pool = self.pool.get('account.account') - stock = self.pool.get('stock.location') - tax_id = [] - account_id = [] - partner_id = None - company_id = None + + # import company as a new partner, supplier=1. + # company_address data used to add address to new partner + partner_value = {'customer': True} + partner_id = company_pool.edi_import_as_partner(cr, uid, edi_document, values=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['partner_address_id'] = self.edi_m2o(cr, uid, partner_address, context=context) + del edi_document['company_id'] + return partner_id + + def edi_get_pricelist(self, cr, uid, partner_id, context=None): + # return value = ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.list0", "Public Pricelist (EUR)"] + partner_model = self.pool.get('res.partner') + partner = partner_model.browse(cr, uid, partner_id, context=context) + pricelist = partner.property_product_pricelist_purchase + if not pricelist: + pricelist = self.pool.get('ir.model.data').get_object(cr, uid, 'purchase', 'list0', context=context) + return self.edi_m2o(cr, uid, pricelist, context=context) + + def edi_get_location(self, cr, uid, partner_id, context=None): + # return value = ["724f93ec-ddd0-11e0-88ec-701a04e25543:stock.stock_location_stock", "Stock"] + partner_model = self.pool.get('res.partner') + partner = partner_model.browse(cr, uid, partner_id, context=context) + location = partner.property_stock_customer + if not location: + location = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock', context=context) + return self.edi_m2o(cr, uid, location, context=context) + + def edi_import(self, cr, uid, edi_document, context=None): if context is None: context = {} - print edi_document - # import company as a new partner, if type==in then supplier=1, else customer=1 - # partner_id field is modified to point to the new partner - # company_address data used to add address to new partner - edi_company_address = edi_document['company_address'] - edi_partner_id = edi_document['partner_id'] - company_name = edi_document['shop_id'][1] - state_id = edi_company_address.get('state_id', False) - state_name = state_id and state_id[1] - country_id = edi_company_address.get('country_id', False) - country_name = country_id and country_id[1] - - country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False - state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, - values={'country_id': country_id, 'code': state_name}, context=context) or False - address_value = { - 'street': edi_company_address.get('street', False), - 'street2': edi_company_address.get('street2', False), - 'zip': edi_company_address.get('zip', False), - 'city': edi_company_address.get('city', False), - 'state_id': state_id, - 'country_id': country_id, - 'email': edi_company_address.get('email', False), - 'phone': edi_company_address.get('phone', False), - - } - partner_value = {'name': company_name} - partner_value.update({'customer': False, 'supplier': True}) - partner_id = partner_pool.create(cr, uid, partner_value, context=context) - address_value.update({'partner_id': partner_id}) - address_id = partner_address_pool.create(cr, uid, address_value, context=context) - partner_address = partner_address_pool.browse(cr, uid, address_id, context=context) - edi_document.update({'partner_address_id':self.edi_m2o(cr, uid, partner_address, context=context)}) - partner = partner_pool.browse(cr, uid, partner_id, context=context) - edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) - location_id = stock.search(cr, uid,[('name','=','Stock')]) - location = stock.browse(cr, uid, location_id[0]) - edi_document.update({'dest_address_id': edi_document['partner_shipping_id'],'location_id': self.edi_m2o(cr, uid, location, context=context)}) - for line in range(len(edi_document['order_line'])): - product_qty = edi_document['order_line'][line]['product_uom_qty'] - edi_document['order_line'][line].update({'product_qty': product_qty,'taxes_id':edi_document['order_line'][line]['tax_id']}) - - # all fields are converted for purchase order import so unnecessary fields are deleted - delete_key = ['sequence','procurement_id','product_uom_qty','company_address','shop_id','create_date','picking_policy','order_policy','partner_order_id','partner_shipping_id','invoice_quantity','partner_invoice_id','price_subtotal','date_confirm'] - for key in delete_key: - if edi_document.has_key(key): - del edi_document[key] - else: - for document in edi_document['order_line']: - if document.has_key(key): - del document[key] - print "in the edi_purchase import",edi_document + model = edi_document['__model'] + assert model == 'sale.order', _('Could not import purchase order') + edi_document['__model'] = self._name + #import company as a new partner + partner_id = self.edi_import_company(cr, uid, edi_document, context=context) + + edi_document['partner_ref'] = edi_document['name'] + edi_document['notes'] = edi_document.get('note', False) + edi_document['pricelist_id'] = self.edi_get_pricelist(cr, uid, partner_id, context=context) + edi_document['location_id'] = self.edi_get_location(cr, uid, partner_id, context=context) + for order_line in edi_document['order_line']: + order_line['product_qty'] = order_line['product_uom_qty'] + date_order = datetime.strptime(edi_document['date_order'], "%Y-%m-%d") + delay = order_line.get('delay', 0.0) + order_line['date_planned'] = (date_order + timedelta(days=delay)).strftime("%Y-%m-%d") + # price_unit = price_unit - discount + discount = order_line.get('discount', 0.0) + price_unit = order_line['price_unit'] + if discount: + price_unit = price_unit * (1 - (discount or 0.0) / 100.0) + order_line['price_unit'] = price_unit + return super(purchase_order,self).edi_import(cr, uid, edi_document, context=context) - purchase_order() class purchase_order_line(osv.osv, ir_edi.edi): diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index 7351afe4a3f..d8a87fec0c9 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -19,9 +19,9 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( - + diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml index 1fbc89db70a..ef3bbb4338b 100644 --- a/addons/purchase/test/edi_purchase_order.yml +++ b/addons/purchase/test/edi_purchase_order.yml @@ -5,7 +5,7 @@ name: jones white supplier: False customer: True - opt_out: False + opt_out: True - I create one Purchase Order - @@ -30,18 +30,56 @@ import netsvc wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'purchase.order',orders.id,'approved', cr) +- + I Tesing of EDI functionality. First I export Purchase Order from my company than import that Order into customer company - !python {model: ir.edi.document}: | order_pool = self.pool.get('purchase.order') - purchase_id = order_pool.search(cr, uid, ref("purchase_order_test")) - orders = order_pool.browse(cr, uid, purchase_id) - import json + order = order_pool.browse(cr, uid, ref("purchase_order_test")) - tokens = self.export_edi(cr, uid, [orders]) + tokens = self.export_edi(cr, uid, [order]) assert tokens, 'Token is not generated' - document = self.get_document(cr, uid, tokens[0]) - document = json.loads(document) - document[0]["__model"] = "sale.order" - document = json.dumps(document) - a = self.import_edi(cr, uid, edi_document = document) - + +- + I import purchase order from EDI Document of sale order +- + !python {model: ir.edi.document}: | + purchase_order_pool = self.pool.get('purchase.order') + edi_document = { + "order_line": [{ + "product_uom_qty": 1.0, + "name": "basic pc", + "product_uom": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_uom_unit", "PCE"], + "sequence": 10, + "price_unit": 150.0, + "__last_update": False, + "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:724f93ec-ddd0-11e0-88ec-701a04e25543:sale.sale_order_line-LXEqeuI-SSP0", + "product_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_product_pc1", "[PC1] Basic PC"] + }], + "order_policy": "manual", + "company_address": { + "city": "Gerompont", + "zip": "1367", + "__last_update": False, + "country_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:base.be", "Belgium"], + "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:base.main_address", + "phone": "(+32).81.81.37.00", + "street": "Chaussee de Namur 40" + }, + "partner_order_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:base.res_partner_address_3", "Thomas Passot, Belgium, Louvain-la-Neuve, Rue de l'Angelique, 1"], + "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:sale.sale_order_test", + "date_order": "2011-09-13", + "partner_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:sale.res_partner_test22", "Junjun wala"], + "__attachments": [], + "__module": "sale", + "amount_total": 150.0, + "amount_untaxed": 150.0, + "name": "SO008", + "__model": "sale.order", + "__last_update": False, + "company_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:base.main_company", "OpenERP S.A."], + "__version": [6, 1], + "pricelist_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.list0", "Public Pricelist (EUR)"] + } + new_purchase_order_id = purchase_order_pool.edi_import(cr, uid, edi_document, context=context) + assert new_purchase_order_id, 'Purchase order is not imported' diff --git a/addons/sale/__openerp__.py b/addons/sale/__openerp__.py index 0e3ec9ed075..c862a4cbbfa 100644 --- a/addons/sale/__openerp__.py +++ b/addons/sale/__openerp__.py @@ -89,6 +89,7 @@ Dashboard for Sales Manager that includes: ], 'demo_xml': ['sale_demo.xml'], 'test': [ + 'test/edi_sale_order.yml', 'test/data_test.yml', 'test/manual_order_policy.yml', 'test/prepaid_order_policy.yml', @@ -100,7 +101,7 @@ Dashboard for Sales Manager that includes: 'test/invoice_on_ordered_qty.yml', 'test/invoice_on_shipped_qty.yml', 'test/sale_report.yml', - 'test/edi_sale_order.yml', + ], 'installable': True, 'active': False, diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py index 7e193fa672c..70a57a8d216 100644 --- a/addons/sale/edi_sale_order.py +++ b/addons/sale/edi_sale_order.py @@ -22,7 +22,7 @@ from osv import fields, osv, orm from base.ir import ir_edi from tools.translate import _ -from datetime import date +from datetime import date, datetime class sale_order(osv.osv, ir_edi.edi): _inherit = 'sale.order' @@ -30,61 +30,44 @@ class sale_order(osv.osv, ir_edi.edi): def edi_export(self, cr, uid, records, edi_struct=None, context=None): """Exports a Sale order""" edi_struct = { + 'company_id': True, # -> to be changed into partner + 'name': True, + 'date_order': True, + 'partner_id': True, + 'partner_order_id': True, #only one address needed + #SO: 'partner_order_id' + #PO: 'partner_address_id' + 'pricelist_id': True, + 'note': True, + #SO: 'note' + #PO: 'notes' + 'amount_total': True, + 'amount_tax': True, + 'amount_untaxed': True, + 'order_line': { + 'sequence': True, + #SO: yes + #PO: No 'name': True, - 'origin' : True, - 'picking_policy': True, - 'order_policy': True, - 'client_order_ref': True, - 'date_order': True, - 'partner_id': True, - 'note': True, - 'amount_untaxed': True, - 'payment_term': True, - 'amount_tax': True, - 'amount_total': True, - 'amount_untaxed': True, - 'pricelist_id': True, - 'incoterm': True, - 'partner_order_id': True, - 'partner_invoice_id': True, - 'partner_shipping_id': True, - 'shipped': True, - 'picked_rate': True, - 'invoice_quantity': True, - 'invoiced': True, - 'invoiced_rate': True, - - 'order_line': { - 'product_uos_qty': True, - 'product_uom': True, - 'sequence': True, - 'price_unit': True, - 'product_uom_qty': True, - 'discount': True, - 'product_uos': True, - 'invoiced': True, - 'delay': True, - 'name': True, - 'notes': True, - 'product_id': True, - 'th_weight': True, - 'product_packaging': True, - 'tax_id': True, - }, - } - partner_pool = self.pool.get('res.partner') - partner_address_pool = self.pool.get('res.partner.address') - company_address_dict = { - 'street': True, - 'street2': True, - 'zip': True, - 'city': True, - 'state_id': True, - 'country_id': True, - 'email': True, - 'phone': True, - + 'delay': True, + #SO: 'delay' : 'date_approve' - 'date_planned' + #PO: 'date_planned': 'date_approve' + 'delay' + + 'product_id': True, + 'product_uom': True, + 'price_unit': True, + 'product_uom_qty': True, + #SO: 'product_uom_qty' + #PO: 'product_qty' + + 'discount': True, + #SO: yes + #PO: No + 'notes': True, + } + } + company_pool = self.pool.get('res.company') edi_doc_list = [] for order in records: # Get EDI doc based on struct. The result will also contain all metadata fields and attachments. @@ -94,101 +77,67 @@ class sale_order(osv.osv, ir_edi.edi): edi_doc = edi_doc[0] # Add company info and address - res = partner_pool.address_get(cr, uid, [order.shop_id.company_id.partner_id.id], ['contact', 'order']) - contact_addr_id = res['contact'] - invoice_addr_id = res['order'] - - address = partner_address_pool.browse(cr, uid, invoice_addr_id, context=context) - edi_company_address_dict = {} - for key, value in company_address_dict.items(): - if not value: - continue - address_rec = getattr(address, key) - if not address_rec: - continue - if key.endswith('_id'): - address_rec = self.edi_m2o(cr, uid, address_rec, context=context) - - edi_company_address_dict[key] = address_rec - + edi_company_document = company_pool.edi_export_address(cr, uid, [order.company_id], context=context)[order.company_id.id] edi_doc.update({ - 'company_address': edi_company_address_dict, + 'company_address': edi_company_document['company_address'], + #'company_logo': edi_company_document['company_logo'],#TODO }) edi_doc_list.append(edi_doc) return edi_doc_list - def edi_import(self, cr, uid, edi_document, context=None): - partner_pool = self.pool.get('res.partner') + def edi_import_company(self, cr, uid, edi_document, context=None): partner_address_pool = self.pool.get('res.partner.address') - model_data_pool = self.pool.get('ir.model.data') - product_pool = self.pool.get('product.product') - product_categ_pool = self.pool.get('product.category') + partner_pool = self.pool.get('res.partner') company_pool = self.pool.get('res.company') - country_pool = self.pool.get('res.country') - state_pool = self.pool.get('res.country.state') - - tax_id = [] - account_id = [] - partner_id = None - company_id = None + + # import company as a new partner, supplier=1. + # company_address data used to add address to new partner + partner_value = {'supplier': True} + partner_id = company_pool.edi_import_as_partner(cr, uid, edi_document, values=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['partner_order_id'] = self.edi_m2o(cr, uid, partner_address, context=context) + edi_document['partner_invoice_id'] = edi_document['partner_order_id'] + edi_document['partner_shipping_id'] = edi_document['partner_order_id'] + del edi_document['company_id'] + return partner_id + + def edi_get_pricelist(self, cr, uid, partner_id, context=None): + # value = ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.list0", "Public Pricelist (EUR)"] + partner_model = self.pool.get('res.partner') + partner = partner_model.browse(cr, uid, partner_id, context=context) + pricelist = partner.property_product_pricelist + if not pricelist: + pricelist = self.pool.get('ir.model.data').get_object(cr, uid, 'product', 'list0', context=context) + return self.edi_m2o(cr, uid, pricelist, context=context) + + def edi_import(self, cr, uid, edi_document, context=None): if context is None: context = {} - # import company as a new partner, if type==in then supplier=1, else customer=1 - # partner_id field is modified to point to the new partner - # company_address data used to add address to new partner - edi_company_address = edi_document['company_address'] - edi_partner_id = edi_document['partner_id'] - company_name = edi_document['company_id'][1] - state_id = edi_company_address.get('state_id', False) - state_name = state_id and state_id[1] - country_id = edi_company_address.get('country_id', False) - country_name = country_id and country_id[1] + model = edi_document['__model'] + assert model == 'purchase.order', _('Could not import sale order') + edi_document['__model'] = self._name + #import company as a new partner + partner_id = self.edi_import_company(cr, uid, edi_document, context=context) - country_id = country_name and self.edi_import_relation(cr, uid, 'res.country', country_name, context=context) or False - state_id = state_name and self.edi_import_relation(cr, uid, 'res.country.state', state_name, - values={'country_id': country_id, 'code': state_name}, context=context) or False - address_value = { - 'street': edi_company_address.get('street', False), - 'street2': edi_company_address.get('street2', False), - 'zip': edi_company_address.get('zip', False), - 'city': edi_company_address.get('city', False), - 'state_id': state_id, - 'country_id': country_id, - 'email': edi_company_address.get('email', False), - 'phone': edi_company_address.get('phone', False), - - } - - partner_value = {'name': company_name} - partner_value.update({'customer': True, 'supplier': False}) - - partner_id = partner_pool.create(cr, uid, partner_value, context=context) - address_value.update({'partner_id': partner_id}) - address_id = partner_address_pool.create(cr, uid, address_value, context=context) - partner_address = partner_address_pool.browse(cr, uid, [address_id], context=context) - partner_address_id = self.edi_o2m(cr, uid, [partner_address], context=context) - partner = partner_pool.browse(cr, uid, partner_id, context=context) - edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context) - edi_document.update({ - 'partner_invoice_id': partner_address_id, - 'partner_order_id': partner_address_id, - 'partner_shipping_id': partner_address_id, - #'product_uom_qty': edi_document['order_line'][0]['product_qty'], - 'delay': 10, - }) - # all fields are converted for sale order import so unnecessary fields are deleted - del edi_document['order_line'][0]['date_planned'] - del edi_document['order_line'][0]['product_qty'] - del edi_document['date_approve'] - del edi_document['validator'] - - del edi_document['location_id'] - del edi_document['partner_address_id'] - del edi_document['company_address'] - del edi_document['company_id'] - del edi_document['warehouse_id'] + date_order = edi_document.get('date_order', False) + edi_document['client_order_ref'] = edi_document['name'] + edi_document['note'] = edi_document.get('notes', False) + edi_document['pricelist_id'] = self.edi_get_pricelist(cr, uid, partner_id, context=context) + order_lines = edi_document['order_line'] + for order_line in order_lines: + order_line['product_uom_qty'] = order_line['product_qty'] + date_order = datetime.strptime(date_order, "%Y-%m-%d") + date_planned = datetime.strptime(order_line['date_planned'], "%Y-%m-%d") + order_line['delay'] = (date_planned - date_order).days return super(sale_order,self).edi_import(cr, uid, edi_document, context=context) sale_order() diff --git a/addons/sale/test/data_test.yml b/addons/sale/test/data_test.yml index 6e5ec1a9738..2b75e27c90a 100644 --- a/addons/sale/test/data_test.yml +++ b/addons/sale/test/data_test.yml @@ -177,6 +177,7 @@ category_id: - res_partner_category_customers0 name: Cleartrail + opt_out: True - I create contact address for Cleartrail. - diff --git a/addons/sale/test/edi_sale_order.yml b/addons/sale/test/edi_sale_order.yml index b7bd018156e..9eb6fc42ce0 100644 --- a/addons/sale/test/edi_sale_order.yml +++ b/addons/sale/test/edi_sale_order.yml @@ -5,7 +5,7 @@ name: Junjun wala supplier: False customer: True - opt_out: False + opt_out: True - I create one Sale Order - @@ -35,17 +35,52 @@ I Tesing of EDI functionality. First I export Sale Order from my company than import that Order into customer company - !python {model: ir.edi.document}: | - import json - invoice_pool = self.pool.get('sale.order') - orders = invoice_pool.browse(cr, uid, ref("sale_order_test")) + sale_order_pool = self.pool.get('sale.order') + orders = sale_order_pool.browse(cr, uid, ref("sale_order_test")) tokens = self.export_edi(cr, uid, [orders]) assert tokens, 'Token is not generated' - document = self.get_document(cr, uid, tokens[0]) - document = json.loads(document) - document[0]["__model"] = "purchase.order" - document = json.dumps(document) - #a = self.import_edi(cr, uid, edi_document = document) - #assert a, 'Invoice is not imported' +- + I import Sale order from EDI Document of purchase order +- + !python {model: ir.edi.document}: | + sale_order_pool = self.pool.get('sale.order') + edi_document = { + "order_line": [{ + "name": "basic pc", + "product_uom": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_uom_unit", "PCE"], + "date_planned": "2011-08-31", + "price_unit": 150.0, + "__last_update": False, + "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:purchase.purchase_order_line-AlhsVDZGoKvJ", + "product_qty": 1.0, + "product_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_product_pc1", "[PC1] Basic PC"] + }], + "partner_address_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.res_partner_address_11", "Sebastien LANGE, France, Alencon, 1 place de l'\u00c9glise"], + "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:purchase.purchase_order_test", + "date_order": "2011-09-12", + "partner_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:purchase.res_partner_test20", "jones white"], + "__attachments": [], + "__module": "purchase", + "amount_total": 150.0, + "company_address": { + "phone": "(+32).81.81.37.00", + "street": "Chaussee de Namur 40", + "city": "Gerompont", + "zip": "1367", + "__last_update": False, + "country_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.be", "Belgium"], + "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:base.main_address", + }, + "amount_untaxed": 150.0, + "name": "PO00011", + "__model": "purchase.order", + "__last_update": False, + "company_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.main_company", "OpenERP S.A."], + "__version": [6, 1], + "pricelist_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.list0", "Public Pricelist (EUR)"] + } + new_sale_order_id = sale_order_pool.edi_import(cr, uid, edi_document, context=context) + assert new_sale_order_id, 'Sale order is not imported' From fa802828877780cb0f1cbab1a45b1009b5d643b2 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 15 Sep 2011 11:00:43 +0530 Subject: [PATCH 046/316] [FIX] edi: correct datas of email_template bzr revid: hmo@tinyerp.com-20110915053043-a6f2d7ecwfbzspu1 --- addons/account/edi_invoice_action_data.xml | 23 +++++++------- addons/account/test/test_edi_invoice.yml | 5 ++-- addons/email_template/email_template.py | 1 + addons/purchase/edi_purchase_order_data.xml | 33 ++++++++++----------- addons/sale/edi_sale_order_data.xml | 28 ++++++++--------- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index fb89e585195..22d3eb7dbdf 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -4,10 +4,10 @@ context.update({'edi_web_invoice_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, +if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')[1], - [object.id], + object.id, context=context) code @@ -26,10 +26,14 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( - ${object.company_id.name} Invoice (Ref ${object.number or 'n/a' }) - ${object.address_invoice_id.email or ''} - - + Mail Template of Invoice For EDI Document + ${object.user_id.user_email or ''} + ${object.user_id.user_email or ''} + + ${object.company_id.name} Invoice (Ref ${object.number or 'n/a' }) + ${object.address_invoice_id.email or ''} + + <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); "> <p> Hello ${object.address_invoice_id.name and ' ' or ''},</p> @@ -44,7 +48,7 @@ ${object.company_id.paypal_account and "<p>It is possible to pay with Payp <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a></div> <div> </div> </div> </div> <p> </p> - + Hello ${object.address_invoice_id.name and ' ' or ''}, You can click on the following link to preview, print and pay invoice: @@ -67,10 +71,7 @@ Thank you for choosing our service! ${object.company_id.name} Contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} - mako - Mail Template of Invoice For EDI Document - account.invoice - ${object.user_id.user_email or ''} + diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index e01e6aaa712..d29fe96fc89 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -123,13 +123,12 @@ - !python {model: account.invoice}: | - invoice_old = self.browse(cr, uid, ref("customer_invoice_test")) - new_partner_id = self.pool.get('res.partner').name_search(cr, uid, invoice_old.company_id.name) + 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]) - assert invoice_new.reference == invoice_old.internal_number, "internal number is not stored in reference" + 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.internal_number == False, "internal number is not reset" assert invoice_new.journal_id.id, "journal id is not selected" diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index 3917b3f2ddb..1a8ba49594d 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -382,5 +382,6 @@ class email_template(osv.osv): if context.has_key('default_type'): del context['default_type'] attachment_ids.append(ir_attachment.create(cr, uid, attachment_data, context)) + return message_id # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index d8a87fec0c9..e99fe687b5d 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -3,11 +3,11 @@ - context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, + context.update({'edi_web_purchase_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase')[1], - [object.id], + object.id, context=context) code @@ -19,23 +19,25 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( - + - ${object.company_id.name} - Purchase Order ${object.name} - ${object.partner_address_id.email} - - True - + Mail Template of Purchase Order For EDI Document + ${object.validator.user_email or ''} + ${object.validator.user_email or ''} + ${object.company_id.name} - Purchase Order ${object.name} + ${object.partner_address_id.email} + + <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); "> <p> Hello ${object.partner_address_id.name and ' ' or ''},</p> <p> You can click on the following link to preview, print and pay invoice: <br/> - <a href="${object._context.get('edi_web_url_view')}">${object._context.get('edi_web_url_view')} </a> + <a href="${object._context.get('edi_web_purchase_url_view')}">${object._context.get('edi_web_purchase_url_view')} </a> </p> @@ -45,12 +47,12 @@ ${object.company_id.paypal_account and "<p>It is possible to pay with Payp <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></div> <div> </div> </div> </div> <p> </p> - + Hello ${object.partner_address_id.name and ' ' or ''}, You can click on the following link to preview, print and pay invoice: - ${object._context.get('edi_web_url_view') or 'n/a'} + ${object._context.get('edi_web_purchase_url_view') or 'n/a'} Order Number: *${object.name}* Amount: *${object.amount_total}* @@ -67,10 +69,7 @@ Thank you for choosing our service! ${object.company_id.name} Contact: ${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''} - mako - Mail Template of Purchase Order For EDI Document - purchase.order - ${object.validator.user_email or ''} + diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml index a9e25bd2562..0e9fa04b12e 100644 --- a/addons/sale/edi_sale_order_data.xml +++ b/addons/sale/edi_sale_order_data.xml @@ -3,11 +3,11 @@ - context.update({'edi_web_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail(cr, + context.update({'edi_web_sale_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) +if not object.partner_id.opt_out: self.pool.get('email.template').send_email(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], - [object.id], + object.id, context=context) code @@ -26,16 +26,18 @@ if not object.partner_id.opt_out: self.pool.get('email.template').generate_mail( - ${object.company_id.name} - Sale Order ${object.name} - ${object.partner_invoice_id.email} - - True - + Mail Template of Sale Order For EDI Document + ${object.user_id.user_email or ''} + ${object.user_id.user_email or ''} + ${object.company_id.name} - Sale Order ${object.name} + ${object.partner_invoice_id.email} + + <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); "> <p> Hello ${object.partner_invoice_id.name and ' ' or ''},</p> <p> You can click on the following link to preview, print and pay invoice: <br/> - <a href="${object._context.get('edi_web_url_view')}">${object._context.get('edi_web_url_view')} </a> + <a href="${object._context.get('edi_web_sale_url_view')}">${object._context.get('edi_web_sale_url_view')} </a> </p> @@ -45,12 +47,12 @@ ${object.company_id.paypal_account and "<p>It is possible to pay with Payp <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></div> <div> </div> </div> </div> <p> </p> - + Hello ${object.partner_invoice_id.name and ' ' or ''}, You can click on the following link to preview, print and pay invoice: - ${object._context.get('edi_web_url_view') or 'n/a'} + ${object._context.get('edi_web_sale_url_view') or 'n/a'} Order Number: *${object.name}* Amount: *${object.amount_total}* @@ -67,10 +69,6 @@ Thank you for choosing our service! ${object.company_id.name} Contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} - mako - Mail Template of Sale Order For EDI Document - sale.order - ${object.user_id.user_email or ''} From cbc18d6479d37c13666056709fe1c2c82204a939 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Thu, 15 Sep 2011 19:02:13 +0530 Subject: [PATCH 047/316] [IMP] improved yml for edi sale,purchase and account invoice bzr revid: han@tinyerp.com-20110915133213-i67qac35o1q1rtyv --- addons/account/test/test_edi_invoice.yml | 7 +++- addons/purchase/test/edi_purchase_order.yml | 39 ++++++++++++++++-- addons/sale/test/edi_sale_order.yml | 44 ++++++++++----------- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index 29c7c626f6d..843892a4573 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -150,11 +150,14 @@ 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', "Imported in voice is not supplier invoice" + assert invoice_new.amount_total == 1010.0, "Amount total is not same" + assert invoice_new.amount_tax == 1000.0, "Amount tax is not same" + assert invoice_new.amount_untaxes == 10.0, "Amount untaxed is not same" product = ['Medium PC','Basic PC'] for inv_line in invoice_new.invoice_line: assert inv_line.account_id.id, "account_id is not taken from product's default" - assert inv_line.product_id.name in product, "product is not in Invoice line" + assert inv_line.product_id.name in ['Medium PC','Basic PC'], "product is not in Invoice line" for inv_tax in invoice_new.tax_line: assert inv_tax.manual, "for tax line manual is not set to True" assert inv_tax.account_id, "for tax_line default accounts is not picked based on the tax config of the DB where it is imported." diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml index ef3bbb4338b..a6dc45ee997 100644 --- a/addons/purchase/test/edi_purchase_order.yml +++ b/addons/purchase/test/edi_purchase_order.yml @@ -21,8 +21,15 @@ price_unit: 150.0 name: 'basic pc' date_planned: '2011-08-31' + order_line: + - product_id: product.product_product_pc3 + product_qty: 10.0 + product_uom: 1 + price_unit: 200.0 + name: 'medium pc' + date_planned: '2011-08-31' - - I Open the sale order + I Open the Purchase order - !python {model: purchase.order}: | @@ -55,6 +62,16 @@ "__last_update": False, "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:724f93ec-ddd0-11e0-88ec-701a04e25543:sale.sale_order_line-LXEqeuI-SSP0", "product_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_product_pc1", "[PC1] Basic PC"] + }, + { + "product_uom_qty": 10.0, + "name": "medium pc", + "product_uom": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_uom_unit", "PCE"], + "sequence": 11, + "price_unit": 200.0, + "__last_update": False, + "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:724f93ec-ddd0-11e0-88ec-701a04e25543:sale.sale_order_line-LXEqeuI-SSP0", + "product_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_product_pc3", "[PC3] Medim PC"] }], "order_policy": "manual", "company_address": { @@ -72,8 +89,8 @@ "partner_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:sale.res_partner_test22", "Junjun wala"], "__attachments": [], "__module": "sale", - "amount_total": 150.0, - "amount_untaxed": 150.0, + "amount_total": 350.0, + "amount_untaxed": 350.0, "name": "SO008", "__model": "sale.order", "__last_update": False, @@ -83,3 +100,19 @@ } new_purchase_order_id = purchase_order_pool.edi_import(cr, uid, edi_document, context=context) assert new_purchase_order_id, 'Purchase order is not imported' + +- + I Checking the sale order become purchase order or not after import +- + !python {model: sale.order}: | + + ids = self.search(cr, uid, [('partner_id','=','OpenERP S.A.')]) + assert ids, 'Order does not have created of party' + order_new = self.browse(cr, uid, ids[0]) + assert order_new.pricelist_id.name == 'Public Pricelist' , "Public Price list is not imported" + assert order_new.amount_total == 350, "Amount total is not same" + assert order_new.amount_untaxed == 350, "untaxed amount is not same" + for sale_line in order_new.order_line: + assert sale_line.name in ['basic pc','medium pc'], "name of product is not in order" + assert sale_line.product_id.name in ['Basic PC','Medium PC'], "name of product is not in order" + assert sale_line.date_order == '2011-09-13' , "date of order is not same" diff --git a/addons/sale/test/edi_sale_order.yml b/addons/sale/test/edi_sale_order.yml index 1756f369ff6..af1b32a6f01 100644 --- a/addons/sale/test/edi_sale_order.yml +++ b/addons/sale/test/edi_sale_order.yml @@ -21,6 +21,12 @@ product_uom: 1 price_unit: 150.0 name: 'basic pc' + order_line: + - product_id: product.product_product_pc3 + product_uom_qty: 10.0 + product_uom: 1 + price_unit: 200.0 + name: 'medium pc' - I Open the sale order - @@ -63,7 +69,7 @@ "partner_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:purchase.res_partner_test20", "jones white"], "__attachments": [], "__module": "purchase", - "amount_total": 150.0, + "amount_total": 350.0, "company_address": { "phone": "(+32).81.81.37.00", "street": "Chaussee de Namur 40", @@ -73,7 +79,7 @@ "country_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.be", "Belgium"], "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:base.main_address", }, - "amount_untaxed": 150.0, + "amount_untaxed": 350.0, "name": "PO00011", "__model": "purchase.order", "__last_update": False, @@ -85,27 +91,17 @@ assert new_sale_order_id, 'Sale order is not imported' - - I Checking the out invoice become in invoice or not after import ======== + I Checking the sale order become purchase order or not after import - - !python {model: account.invoice}: | + !python {model: purchase.order}: | - 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]) - 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.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' - product = ['Medium PC','Basic PC'] - for inv_line in invoice_new.invoice_line: - assert inv_line.account_id.id, "account_id is not taken from product's default" - assert inv_line.product_id.name in product, "product is not in Invoice line" - #print '-----------------=================',inv_line.product_id.quantity - assert inv_line.product_id.price_subtotal == 375, 'subtotal is not matched' - #assert inv_line.producr_id.quantity - for inv_tax in invoice_new.tax_line: - assert inv_tax.manual, "for tax line manual is not set to True" - assert inv_tax.account_id, "for tax_line default accounts is not picked based on the tax config of the DB where it is imported." + ids = self.search(cr, uid, [('partner_id','=','OpenERP S.A.')]) + assert ids, 'Order does not have created of party' + order_new = self.browse(cr, uid, ids[0]) + assert order_new.pricelist_id.name == 'Public Pricelist' , "Public Price list is not imported" + assert order_new.amount_total == 350, "Amount total is not same" + assert order_new.amount_untaxed == 350, "untaxed amount is not same" + for purchase_line in order_new.order_line: + assert purchase_line.name in ['basic pc','medium pc'], "name of product is not in order" + assert purchase_line.product_id.name in ['Basic PC','Medium PC'], "name of product is not in order" + assert purchase_line.date_planned == '2011-09-13' , "date of planned order is not same" From a2df13b0a197934cde5f2f2a725bcba3135ce565 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Thu, 15 Sep 2011 19:13:01 +0530 Subject: [PATCH 048/316] [IMP] edi: modified web_url bzr revid: hmo@tinyerp.com-20110915134301-jbjssv0p43v6lczm --- addons/account/edi_invoice_action_data.xml | 2 +- addons/purchase/edi_purchase_order_data.xml | 2 +- addons/sale/edi_sale_order_data.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/account/edi_invoice_action_data.xml b/addons/account/edi_invoice_action_data.xml index 22d3eb7dbdf..517628b434c 100644 --- a/addons/account/edi_invoice_action_data.xml +++ b/addons/account/edi_invoice_action_data.xml @@ -3,7 +3,7 @@ - context.update({'edi_web_invoice_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, 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' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'email_template_edi_invoice')[1], diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index e99fe687b5d..7e6482b6ca1 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -3,7 +3,7 @@ - context.update({'edi_web_purchase_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) + context.update({'edi_web_purchase_url_view': '%s/web/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'email_template_edi_purchase')[1], diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml index 0e9fa04b12e..66e38f40360 100644 --- a/addons/sale/edi_sale_order_data.xml +++ b/addons/sale/edi_sale_order_data.xml @@ -3,7 +3,7 @@ - context.update({'edi_web_sale_url_view': '%s/edi/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) + context.update({'edi_web_sale_url_view': '%s/web/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) if not object.partner_id.opt_out: self.pool.get('email.template').send_email(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], From c17142a45bc329931bb7ba59550fcdb4d7624b0c Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 16 Sep 2011 12:13:19 +0530 Subject: [PATCH 049/316] [FIX] edi: correct yml and remove stuff to change model into sale and puchase EDI bzr revid: hmo@tinyerp.com-20110916064319-63zc227t9g8cxao2 --- addons/account/test/test_edi_invoice.yml | 3 -- addons/purchase/edi_purchase_order.py | 3 -- addons/purchase/test/edi_purchase_order.yml | 20 +++++------ addons/sale/edi_sale_order.py | 11 +++--- addons/sale/test/edi_sale_order.yml | 40 +++++++++++++++------ 5 files changed, 45 insertions(+), 32 deletions(-) diff --git a/addons/account/test/test_edi_invoice.yml b/addons/account/test/test_edi_invoice.yml index 843892a4573..0285e541156 100644 --- a/addons/account/test/test_edi_invoice.yml +++ b/addons/account/test/test_edi_invoice.yml @@ -151,9 +151,6 @@ 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.amount_total == 1010.0, "Amount total is not same" - assert invoice_new.amount_tax == 1000.0, "Amount tax is not same" - assert invoice_new.amount_untaxes == 10.0, "Amount untaxed is not same" product = ['Medium PC','Basic PC'] for inv_line in invoice_new.invoice_line: assert inv_line.account_id.id, "account_id is not taken from product's default" diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index cb19f57c103..8e3979eb8bd 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -124,9 +124,6 @@ class purchase_order(osv.osv, ir_edi.edi): if context is None: context = {} - model = edi_document['__model'] - assert model == 'sale.order', _('Could not import purchase order') - edi_document['__model'] = self._name #import company as a new partner partner_id = self.edi_import_company(cr, uid, edi_document, context=context) diff --git a/addons/purchase/test/edi_purchase_order.yml b/addons/purchase/test/edi_purchase_order.yml index a6dc45ee997..07f5179a65a 100644 --- a/addons/purchase/test/edi_purchase_order.yml +++ b/addons/purchase/test/edi_purchase_order.yml @@ -68,7 +68,7 @@ "name": "medium pc", "product_uom": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_uom_unit", "PCE"], "sequence": 11, - "price_unit": 200.0, + "price_unit": 20.0, "__last_update": False, "__id": "724f93ec-ddd0-11e0-88ec-701a04e25543:724f93ec-ddd0-11e0-88ec-701a04e25543:sale.sale_order_line-LXEqeuI-SSP0", "product_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.product_product_pc3", "[PC3] Medim PC"] @@ -88,13 +88,13 @@ "date_order": "2011-09-13", "partner_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:sale.res_partner_test22", "Junjun wala"], "__attachments": [], - "__module": "sale", + "__module": "purchase", "amount_total": 350.0, "amount_untaxed": 350.0, "name": "SO008", - "__model": "sale.order", + "__model": "purchase.order", "__last_update": False, - "company_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:base.main_company", "OpenERP S.A."], + "company_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:base.main_company", "Supplier S.A."], "__version": [6, 1], "pricelist_id": ["724f93ec-ddd0-11e0-88ec-701a04e25543:product.list0", "Public Pricelist (EUR)"] } @@ -104,15 +104,15 @@ - I Checking the sale order become purchase order or not after import - - !python {model: sale.order}: | + !python {model: purchase.order}: | - ids = self.search(cr, uid, [('partner_id','=','OpenERP S.A.')]) + ids = self.search(cr, uid, [('partner_id','=','Supplier S.A.'), ('partner_ref', '=', 'SO008')]) assert ids, 'Order does not have created of party' order_new = self.browse(cr, uid, ids[0]) assert order_new.pricelist_id.name == 'Public Pricelist' , "Public Price list is not imported" assert order_new.amount_total == 350, "Amount total is not same" assert order_new.amount_untaxed == 350, "untaxed amount is not same" - for sale_line in order_new.order_line: - assert sale_line.name in ['basic pc','medium pc'], "name of product is not in order" - assert sale_line.product_id.name in ['Basic PC','Medium PC'], "name of product is not in order" - assert sale_line.date_order == '2011-09-13' , "date of order is not same" + for purchase_line in order_new.order_line: + assert purchase_line.name in ['basic pc','medium pc'], "name of product is not in order" + assert purchase_line.product_id.name in ['Basic PC','Medium PC'], "name of product is not in order" + assert purchase_line.date_order == '2011-09-13' , "date of order is not same" diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py index 70a57a8d216..1baad0f59b5 100644 --- a/addons/sale/edi_sale_order.py +++ b/addons/sale/edi_sale_order.py @@ -122,9 +122,6 @@ class sale_order(osv.osv, ir_edi.edi): if context is None: context = {} - model = edi_document['__model'] - assert model == 'purchase.order', _('Could not import sale order') - edi_document['__model'] = self._name #import company as a new partner partner_id = self.edi_import_company(cr, uid, edi_document, context=context) @@ -135,9 +132,11 @@ class sale_order(osv.osv, ir_edi.edi): order_lines = edi_document['order_line'] for order_line in order_lines: order_line['product_uom_qty'] = order_line['product_qty'] - date_order = datetime.strptime(date_order, "%Y-%m-%d") - date_planned = datetime.strptime(order_line['date_planned'], "%Y-%m-%d") - order_line['delay'] = (date_planned - date_order).days + date_planned = order_line['date_planned'] + delay = 0 + if date_order and date_planned: + delay = (datetime.strptime(date_planned, "%Y-%m-%d") - datetime.strptime(date_order, "%Y-%m-%d")).days + order_line['delay'] = delay return super(sale_order,self).edi_import(cr, uid, edi_document, context=context) sale_order() diff --git a/addons/sale/test/edi_sale_order.yml b/addons/sale/test/edi_sale_order.yml index af1b32a6f01..cf8da5f1efb 100644 --- a/addons/sale/test/edi_sale_order.yml +++ b/addons/sale/test/edi_sale_order.yml @@ -56,19 +56,29 @@ "order_line": [{ "name": "basic pc", "product_uom": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_uom_unit", "PCE"], - "date_planned": "2011-08-31", + "date_planned": "2011-09-30", "price_unit": 150.0, "__last_update": False, "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:purchase.purchase_order_line-AlhsVDZGoKvJ", "product_qty": 1.0, "product_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_product_pc1", "[PC1] Basic PC"] + }, + { + "name": "medium pc", + "product_uom": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_uom_unit", "PCE"], + "date_planned": "2011-09-15", + "price_unit": 100.0, + "__last_update": False, + "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:purchase.purchase_order_line-AlhsVDZGoKvJ", + "product_qty": 2.0, + "product_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.product_product_pc3", "[PC3] Medium PC"] }], "partner_address_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.res_partner_address_11", "Sebastien LANGE, France, Alencon, 1 place de l'\u00c9glise"], "__id": "5af1272e-dd26-11e0-b65e-701a04e25543:purchase.purchase_order_test", "date_order": "2011-09-12", "partner_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:purchase.res_partner_test20", "jones white"], "__attachments": [], - "__module": "purchase", + "__module": "sale", "amount_total": 350.0, "company_address": { "phone": "(+32).81.81.37.00", @@ -81,9 +91,9 @@ }, "amount_untaxed": 350.0, "name": "PO00011", - "__model": "purchase.order", + "__model": "sale.order", "__last_update": False, - "company_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.main_company", "OpenERP S.A."], + "company_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:base.main_company", "Client S.A."], "__version": [6, 1], "pricelist_id": ["5af1272e-dd26-11e0-b65e-701a04e25543:product.list0", "Public Pricelist (EUR)"] } @@ -93,15 +103,25 @@ - I Checking the sale order become purchase order or not after import - - !python {model: purchase.order}: | + !python {model: sale.order}: | - ids = self.search(cr, uid, [('partner_id','=','OpenERP S.A.')]) + ids = self.search(cr, uid, [('partner_id','=','Client S.A.'), ('client_order_ref', '=', 'PO00011')]) assert ids, 'Order does not have created of party' order_new = self.browse(cr, uid, ids[0]) assert order_new.pricelist_id.name == 'Public Pricelist' , "Public Price list is not imported" assert order_new.amount_total == 350, "Amount total is not same" assert order_new.amount_untaxed == 350, "untaxed amount is not same" - for purchase_line in order_new.order_line: - assert purchase_line.name in ['basic pc','medium pc'], "name of product is not in order" - assert purchase_line.product_id.name in ['Basic PC','Medium PC'], "name of product is not in order" - assert purchase_line.date_planned == '2011-09-13' , "date of planned order is not same" + assert len(order_new.order_line) == 2, "sale lines are not same" + for sale_line in order_new.order_line: + if sale_line.name == 'basic pc': + assert sale_line.delay == 18 , "delay is not same" + assert sale_line.product_uom.name == "PCE" , "uom is not same" + assert sale_line.price_unit == 150 , "price unit is not same" + assert sale_line.product_uom_qty == 1 , "product qty is not same" + elif sale_line.name == 'medium pc': + assert sale_line.delay == 3 , "delay is not same" + assert sale_line.product_uom.name == "PCE" , "uom is not same" + assert sale_line.price_unit == 100 , "price unit is not same" + assert sale_line.product_uom_qty == 2 , "product qty is not same" + else: + assert 'wrong product imported in sale lines' From 16fd6962a098ad8f1a5e80fa769267281377e94f Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 16 Sep 2011 15:06:11 +0530 Subject: [PATCH 050/316] [FIX] edi: typo and add some fields in export dict bzr revid: hmo@tinyerp.com-20110916093611-p5ee9b7for1gqx6a --- addons/purchase/edi_purchase_order.py | 8 +++++--- addons/sale/edi_sale_order.py | 8 +++++--- addons/sale/edi_sale_order_data.xml | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 8e3979eb8bd..e2791164c31 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -32,7 +32,8 @@ class purchase_order(osv.osv, ir_edi.edi): edi_struct = { 'company_id': True, # -> to be changed into partner 'name': True, - + 'partner_ref': True, + 'origin': True, 'date_order': True, 'partner_id': True, 'partner_address_id': True, #only one address needed @@ -50,12 +51,13 @@ class purchase_order(osv.osv, ir_edi.edi): 'order_line': { 'name': True, 'date_planned': True, - #SO: 'delay' : 'date_approve' - 'date_planned' - #PO: 'date_planned': 'date_approve' + 'delay' + #SO: 'delay' : 'date_order' - 'date_planned' + #PO: 'date_planned': 'date_order' + 'delay' 'product_id': True, 'product_uom': True, 'price_unit': True, + 'price_subtotal': True, 'product_qty': True, #SO: 'product_uom_qty' #PO: 'product_qty' diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py index 1baad0f59b5..e444f1371eb 100644 --- a/addons/sale/edi_sale_order.py +++ b/addons/sale/edi_sale_order.py @@ -32,6 +32,8 @@ class sale_order(osv.osv, ir_edi.edi): edi_struct = { 'company_id': True, # -> to be changed into partner 'name': True, + 'client_order_ref': True, + 'origin': True, 'date_order': True, 'partner_id': True, 'partner_order_id': True, #only one address needed @@ -50,8 +52,8 @@ class sale_order(osv.osv, ir_edi.edi): #PO: No 'name': True, 'delay': True, - #SO: 'delay' : 'date_approve' - 'date_planned' - #PO: 'date_planned': 'date_approve' + 'delay' + #SO: 'delay' : 'date_order' - 'date_planned' + #PO: 'date_planned': 'date_order' + 'delay' 'product_id': True, 'product_uom': True, @@ -59,7 +61,7 @@ class sale_order(osv.osv, ir_edi.edi): 'product_uom_qty': True, #SO: 'product_uom_qty' #PO: 'product_qty' - + 'price_subtotal': True, 'discount': True, #SO: yes #PO: No diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml index 66e38f40360..04683d1a230 100644 --- a/addons/sale/edi_sale_order_data.xml +++ b/addons/sale/edi_sale_order_data.xml @@ -4,7 +4,7 @@ context.update({'edi_web_sale_url_view': '%s/web/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -if not object.partner_id.opt_out: self.pool.get('email.template').send_email(cr, +if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], object.id, From f8d9aeaca5dc410121495a046b55ac99ad051fc1 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 16 Sep 2011 15:40:31 +0530 Subject: [PATCH 051/316] [IMP] edi: Imporve Email Template of sale,purchase bzr revid: hmo@tinyerp.com-20110916101031-3lspjfm35e958qbr --- addons/purchase/edi_purchase_order_data.xml | 10 ++++------ addons/sale/edi_sale_order_data.xml | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/addons/purchase/edi_purchase_order_data.xml b/addons/purchase/edi_purchase_order_data.xml index 7e6482b6ca1..02ecb24b9ba 100644 --- a/addons/purchase/edi_purchase_order_data.xml +++ b/addons/purchase/edi_purchase_order_data.xml @@ -36,30 +36,28 @@ if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, <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); "> <p> Hello ${object.partner_address_id.name and ' ' or ''},</p> -<p> You can click on the following link to preview, print and pay invoice: <br/> +<p> You can click on the following link to preview purchase order: <br/> <a href="${object._context.get('edi_web_purchase_url_view')}">${object._context.get('edi_web_purchase_url_view')} </a> </p> -<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Confirm date: ${object.date_approve or 'n/a'}<br /> Your contact: <a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></p> +<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Order date: ${object.date_order or 'n/a'}<br /> Your contact: <a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></p> -${object.company_id.paypal_account and "<p>It is possible to pay with Paypal: <br/> <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s\"><img src=\"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif\" style=\"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;\"/></a> </p>"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.validator.user_email or ''}?subject=Order%20${object.name}">${object.validator.name}</a></div> <div> </div> </div> </div> <p> </p> Hello ${object.partner_address_id.name and ' ' or ''}, -You can click on the following link to preview, print and pay invoice: +You can click on the following link to preview Purchase Order: ${object._context.get('edi_web_purchase_url_view') or 'n/a'} Order Number: *${object.name}* Amount: *${object.amount_total}* -Approve date: ${object.date_approve or 'n/a'} +Order date: ${object.date_order or 'n/a'} Your contact: ${object.validator.name} ${object.validator.user_email and '<%s>'%(object.validator.user_email) or ''} -${object.company_id.paypal_account and "It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} If you have any question, do not hesitate to reply directly to this e-mail. diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml index 04683d1a230..33b65b4c031 100644 --- a/addons/sale/edi_sale_order_data.xml +++ b/addons/sale/edi_sale_order_data.xml @@ -36,30 +36,28 @@ if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, <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); "> <p> Hello ${object.partner_invoice_id.name and ' ' or ''},</p> -<p> You can click on the following link to preview, print and pay invoice: <br/> +<p> You can click on the following link to preview sale order : <br/> <a href="${object._context.get('edi_web_sale_url_view')}">${object._context.get('edi_web_sale_url_view')} </a> </p> -<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Confirm date: ${object.date_confirm or 'n/a'}<br /> Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></p> +<p style="border-left: 1px solid #8e0000; margin-left: 30px;"> <strong>REFERENCES</strong><br /> Order number: <strong>${object.name}</strong><br /> Order amount: <strong>${object.amount_total} </strong><br /> Order date: ${object.date_order or 'n/a'}<br /> Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></p> -${object.company_id.paypal_account and "<p>It is possible to pay with Paypal: <br/> <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s\"><img src=\"https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif\" style=\"margin-left: 100px; border: 0px; padding: 1px; text-decoration: none;\"/></a> </p>"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} <p> If you have any question, do not hesitate to reply directly to this e-mail.</p> <p> Thank you for choosing OpenERP!<br /> </p> <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-image: url(http://www.openerp.com/sites/default/files/red_gradient_bg.png); 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>${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); "> <div> Contact:<a href="mailto:${object.user_id.user_email or ''}?subject=Order%20${object.name}">${object.user_id.name}</a></div> <div> </div> </div> </div> <p> </p> Hello ${object.partner_invoice_id.name and ' ' or ''}, -You can click on the following link to preview, print and pay invoice: +You can click on the following link to preview sale order: ${object._context.get('edi_web_sale_url_view') or 'n/a'} Order Number: *${object.name}* Amount: *${object.amount_total}* -Confirm date: ${object.date_confirm or 'n/a'} +Order date: ${object.date_order or 'n/a'} Your contact: ${object.user_id.name} ${object.user_id.user_email and '<%s>'%(object.user_id.user_email) or ''} -${object.company_id.paypal_account and "It is possible to pay with Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=%s&item_name=OpenERP%%20Invoice%%20%s&invoice=%s&amount=%s&currency_code=%s&button_subtype=services&no_note=1&bn=OpenERP_Invoice_PayNow_%s"%(object.company_id.paypal_account, object.name and object.name.replace('/','%2f') or '', object.name and object.name.replace('/','%2f') or '', object.amount_total) or ''} If you have any question, do not hesitate to reply directly to this e-mail. From b3398647231a9d7ef414e2185f160c44773ac312 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Fri, 16 Sep 2011 17:45:54 +0530 Subject: [PATCH 052/316] [imp] bzr revid: han@tinyerp.com-20110916121554-t3wt2v075jl5141u --- addons/sale/edi_sale_order_data.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/edi_sale_order_data.xml b/addons/sale/edi_sale_order_data.xml index 66e38f40360..04683d1a230 100644 --- a/addons/sale/edi_sale_order_data.xml +++ b/addons/sale/edi_sale_order_data.xml @@ -4,7 +4,7 @@ context.update({'edi_web_sale_url_view': '%s/web/view_edi?db=%s&token=%s' %(self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url'),cr.dbname, self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0])}) -if not object.partner_id.opt_out: self.pool.get('email.template').send_email(cr, +if not object.partner_id.opt_out: self.pool.get('email.template').send_mail(cr, uid, self.pool.get('ir.model.data').get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1], object.id, From 95b859a4f9d7af4069c53bde065bd4a860c729c2 Mon Sep 17 00:00:00 2001 From: "Hardik Ansodariy (OpenERP)" Date: Tue, 20 Sep 2011 14:28:46 +0530 Subject: [PATCH 053/316] [imp] set currency id bzr revid: han@tinyerp.com-20110920085846-dxdr6fbjtw7ltedy --- addons/purchase/edi_purchase_order.py | 3 ++- addons/sale/edi_sale_order.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/purchase/edi_purchase_order.py b/addons/purchase/edi_purchase_order.py index 31017daceb1..9119485bffc 100644 --- a/addons/purchase/edi_purchase_order.py +++ b/addons/purchase/edi_purchase_order.py @@ -73,12 +73,13 @@ class purchase_order(osv.osv, ir_edi.edi): if not edi_doc: continue edi_doc = edi_doc[0] + currency = order.company_id.currency_id # Add company info and address edi_company_document = company_pool.edi_export_address(cr, uid, [order.company_id], context=context)[order.company_id.id] edi_doc.update({ 'company_address': edi_company_document['company_address'], - 'currency_id': edi_company_document['currency_id'], + 'currency_id': currency and self.edi_m2o(cr, uid, currency, context=context) or False, #'company_logo': edi_company_document['company_logo'],#TODO }) edi_doc_list.append(edi_doc) diff --git a/addons/sale/edi_sale_order.py b/addons/sale/edi_sale_order.py index eddeb618926..69165de9b85 100644 --- a/addons/sale/edi_sale_order.py +++ b/addons/sale/edi_sale_order.py @@ -77,12 +77,12 @@ class sale_order(osv.osv, ir_edi.edi): if not edi_doc: continue edi_doc = edi_doc[0] - + currency = order.company_id.currency_id # Add company info and address edi_company_document = company_pool.edi_export_address(cr, uid, [order.company_id], context=context)[order.company_id.id] edi_doc.update({ 'company_address': edi_company_document['company_address'], - 'currency_id': edi_company_document['currency_id'], + 'currency_id': currency and self.edi_m2o(cr, uid, currency, context=context) or False, #'company_logo': edi_company_document['company_logo'],#TODO }) edi_doc_list.append(edi_doc) From ad61a880bf166d953d38774c437ec8b69bde7b3e Mon Sep 17 00:00:00 2001 From: "ARA (OpenERP)" Date: Wed, 28 Sep 2011 17:43:31 +0530 Subject: [PATCH 054/316] [FIX] hr-expense : incmplete handling of canceld and reopened invoices lp bug: https://launchpad.net/bugs/808704 fixed bzr revid: ara@tinyerp.com-20110928121331-p3x76mmel6ity9fs --- addons/hr_expense/hr_expense.py | 5 +++++ addons/hr_expense/hr_expense_view.xml | 1 + addons/hr_expense/hr_expense_workflow.xml | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/addons/hr_expense/hr_expense.py b/addons/hr_expense/hr_expense.py index 2dc6ad090ac..b671705d769 100644 --- a/addons/hr_expense/hr_expense.py +++ b/addons/hr_expense/hr_expense.py @@ -82,6 +82,7 @@ class hr_expense_expense(osv.osv): ('accepted', 'Approved'), ('invoiced', 'Invoiced'), ('paid', 'Reimbursed'), + ('invoice_except', 'Invoice Exception'), ('cancelled', 'Refused')], 'State', readonly=True, help='When the expense request is created the state is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the state is \'Waiting Confirmation\'.\ \nIf the admin accepts it, the state is \'Accepted\'.\n If an invoice is made for the expense request, the state is \'Invoiced\'.\n If the expense is paid to user, the state is \'Reimbursed\'.'), @@ -224,6 +225,10 @@ class hr_expense_expense(osv.osv): res = inv_id return res + def action_invoice_cancel(self, cr, uid, ids, context=None): + self.write(cr, uid, ids, {'state': 'invoice_except'}, context=context) + return True + hr_expense_expense() class product_product(osv.osv): diff --git a/addons/hr_expense/hr_expense_view.xml b/addons/hr_expense/hr_expense_view.xml index 786dc6beee2..a832191bb90 100644 --- a/addons/hr_expense/hr_expense_view.xml +++ b/addons/hr_expense/hr_expense_view.xml @@ -106,6 +106,7 @@