diff --git a/base_import_log/__init__.py b/base_import_log/__init__.py
index e4f68e2..e283f40 100644
--- a/base_import_log/__init__.py
+++ b/base_import_log/__init__.py
@@ -18,5 +18,5 @@
# along with this program. If not, see .
#
##############################################################################
-import models
+from . import models
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/base_import_log/models/__init__.py b/base_import_log/models/__init__.py
index 5ea3222..5e71ae5 100644
--- a/base_import_log/models/__init__.py
+++ b/base_import_log/models/__init__.py
@@ -18,6 +18,6 @@
# along with this program. If not, see .
#
##############################################################################
-import error_log
+from . import error_log
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/sale_order_import/__init__.py b/sale_order_import/__init__.py
index 8bc92bb..a42433c 100644
--- a/sale_order_import/__init__.py
+++ b/sale_order_import/__init__.py
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import models
-import wizard
+from . import models
+from . import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
diff --git a/sale_order_import/__openerp__.py b/sale_order_import/__openerp__.py
index 642df76..a90bb7e 100644
--- a/sale_order_import/__openerp__.py
+++ b/sale_order_import/__openerp__.py
@@ -20,7 +20,7 @@
'category': 'Sales Management',
'version': '8.0.1.0',
'author': 'Rooms For (Hong Kong) T/A OSCG',
- 'depends': ['sale_stock', 'base_import_log', 'account_voucher'],
+ 'depends': ['sale_stock', 'base_import_log', 'account_voucher','sale_management'],
'website': 'www.openerp-asia.net',
'description': """
Imports sales data and processes the following:
diff --git a/sale_order_import/doc/ESH_TransactionImportFormats_151022.xlsx b/sale_order_import/doc/ESH_TransactionImportFormats_151022.xlsx
new file mode 100644
index 0000000..f1d2867
Binary files /dev/null and b/sale_order_import/doc/ESH_TransactionImportFormats_151022.xlsx differ
diff --git a/sale_order_import/doc/TransactionAutomationRequirements.pdf b/sale_order_import/doc/TransactionAutomationRequirements.pdf
new file mode 100644
index 0000000..6739229
Binary files /dev/null and b/sale_order_import/doc/TransactionAutomationRequirements.pdf differ
diff --git a/sale_order_import/doc/sale_imort_test.csv b/sale_order_import/doc/sale_imort_test.csv
new file mode 100644
index 0000000..1971b07
--- /dev/null
+++ b/sale_order_import/doc/sale_imort_test.csv
@@ -0,0 +1,5 @@
+Group,Customer,Line Product,Line Description,Line Unit Price,Line Qty,Line Tax,Notes,Pricelist,Warehouse,Picking Policy,Order Policy
+a,Agrolait,DVD,ニンテンドー3DS シルバー,16000,1,Tax 15.00%,,Public Pricelist,YourCompany,Deliver each product when available,On Demand
+a,Agrolait,HEAD,東芝 ロボット掃除機 トルネオ ロボ イエロー VC-RVD1-R,58000,1,Tax 15.00%,,Public Pricelist,YourCompany,Deliver each product when available,On Demand
+b,China Export,LAP-E5,PANASONIC MC-RX1S-W レッド RULO(ルーロ) [ロボット掃除機],75000,1,Tax 15.00%,,Public Pricelist,YourCompany,Deliver each product when available,On Demand
+c,Best Designers,HEAD,東芝 ロボット掃除機 トルネオ ロボ イエロー VC-RVD1-R,58000,1,Tax 15.00%,,Public Pricelist,YourCompany,Deliver each product when available,On Demand
diff --git a/sale_order_import/models/__init__.py b/sale_order_import/models/__init__.py
index 4951d10..fed0bed 100644
--- a/sale_order_import/models/__init__.py
+++ b/sale_order_import/models/__init__.py
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import sale
-import sale_import_default
+from . import sale
+from . import sale_import_default
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/sale_order_import/views/sale_import_default.xml b/sale_order_import/views/sale_import_default.xml
index 5d3f902..059725d 100644
--- a/sale_order_import/views/sale_import_default.xml
+++ b/sale_order_import/views/sale_import_default.xml
@@ -24,7 +24,7 @@
+ action="sale_import_default_action" sequence="10" groups="sales_team.group_sale_salesman_all_leads"/>
diff --git a/sale_order_import/wizard/__init__.py b/sale_order_import/wizard/__init__.py
index 7751c8f..9fb1b26 100644
--- a/sale_order_import/wizard/__init__.py
+++ b/sale_order_import/wizard/__init__.py
@@ -19,6 +19,6 @@
#
##############################################################################
-import import_sale
+from . import import_sale
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/sale_order_import/wizard/import_sale.py b/sale_order_import/wizard/import_sale.py
index 345fd4d..c23ccea 100644
--- a/sale_order_import/wizard/import_sale.py
+++ b/sale_order_import/wizard/import_sale.py
@@ -17,10 +17,13 @@
import os
import csv
-import StringIO
+import io
from tempfile import TemporaryFile
from datetime import datetime
import base64
+from base64 import encodestring
+from odoo.tools import pycompat
+
# import xlrd
import sys
import urllib
@@ -124,7 +127,8 @@ def _get_taxes(self, tax_from_chunk, taxes, error_line_vals):
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Tax: ') + tax_name + _(' Not Found!') + '\n'
error_line_vals['error'] = True
else:
- taxes.append(tax.id)
+ for taxdata in tax:
+ taxes.append(taxdata.id)
@api.model
def _check_csv_format(self, row):
@@ -132,7 +136,7 @@ def _check_csv_format(self, row):
try:
r.decode('utf-8')
except:
- raise Warning(_('Import Error!'),_('Please prepare a CSV file with UTF-8 encoding.!'))
+ raise Warning(_('Please prepare a CSV file with UTF-8 encoding.!'))
@api.model
def _update_error_log(self, error_log_id, error_line_vals, ir_attachment, model, row_no, order_group_value):
@@ -160,17 +164,17 @@ def _update_error_log(self, error_log_id, error_line_vals, ir_attachment, model,
@api.model
def _get_order_id(self, order_data, item, error_log_id):
order_vals = {
- 'name' : '/',
+ 'name' : 'New', #'/', # odoo11
'partner_id' : order_data['partner_id'],
'partner_invoice_id' : order_data['partner_invoice_id'],
'pricelist_id' : order_data['pricelist_id'],
- 'location_id': order_data['location_id'],
+# 'location_id': order_data['location_id'], # odoo11
'partner_shipping_id' : order_data['partner_shipping_id'],
- 'payment_term': order_data['payment_term'],
+ 'payment_term_id': order_data['payment_term'],
'state' : 'draft',
- 'order_policy' : order_data['order_policy'],
+# 'order_policy' : order_data['order_policy'], # odoo11
'picking_policy': order_data['picking_policy'],
- 'currency_id' : order_data['currency_id'],
+# 'currency_id' : order_data['currency_id'], # odoo11
'note': order_data['note'],
'error_log_id': error_log_id,
'imported_order': True,
@@ -186,7 +190,7 @@ def _get_orderline_id(self, so_line, order_id):
'product_id' : so_line['product_id'],
'product_uom_qty' : so_line['product_uom_qty'],
'product_uom': so_line['product_uom'],
- 'invoiced' : False,
+# 'invoiced' : False, # odoo11
'price_unit' : so_line['price_unit'],
'state' : so_line['state'],
'tax_id': [(6, 0, so_line['tax_id'])],
@@ -230,26 +234,48 @@ def import_sale_data(self):
'datas': self.input_file,
'datas_fname': self.datas_fname})
- fileobj = TemporaryFile('w+')
- fileobj.write(base64.decodestring(self.input_file))
- fileobj.seek(0)
- reader = csv.reader(fileobj)
-
- line = 0
- for row in reader:
- line += 1
- if line == 1:#Get the index of header and skip the first line
- order_group = row.index('Group')
- partner_id = row.index('Customer')
- product_id = row.index('Line Product')
- line_name = row.index('Line Description')
- price_unit = row.index('Line Unit Price')
- product_qty = row.index('Line Qty')
- taxes_id = row.index('Line Tax')
- notes = row.index('Notes')
- pricelist_id = row.index('Pricelist')
- warehouse_id = row.index('Warehouse')
- continue
+# fileobj = TemporaryFile('w+')
+# fileobj.write(base64.b64decode(self.input_file))
+# fileobj.seek(0)
+# reader = csv.reader(fileobj)
+
+ # new code to read csv
+ csv_data = base64.decodestring(self.input_file)
+ csv_iterator = pycompat.csv_reader(
+ io.BytesIO(csv_data),
+ quotechar='"',
+ delimiter=','
+ )
+ fields = next(csv_iterator)
+
+ order_group = fields.index('Group')
+ partner_id = fields.index('Customer')
+ product_id = fields.index('Line Product')
+ line_name = fields.index('Line Description')
+ price_unit = fields.index('Line Unit Price')
+ product_qty = fields.index('Line Qty')
+ taxes_id = fields.index('Line Tax')
+ notes = fields.index('Notes')
+ pricelist_id = fields.index('Pricelist')
+ warehouse_id = fields.index('Warehouse')
+
+# line = 1
+ for row in csv_iterator:
+# line += 1
+
+# if line == 1:#Get the index of header and skip the first line
+#
+# order_group = row.index('Group')
+# partner_id = row.index('Customer')
+# product_id = row.index('Line Product')
+# line_name = row.index('Line Description')
+# price_unit = row.index('Line Unit Price')
+# product_qty = row.index('Line Qty')
+# taxes_id = row.index('Line Tax')
+# notes = row.index('Notes')
+# pricelist_id = row.index('Pricelist')
+# warehouse_id = row.index('Warehouse')
+# continue
check_list = []# Below logic for is row values are empty on all columns then skip that line.
order_group_value = row[order_group].strip()
@@ -258,10 +284,10 @@ def import_sale_data(self):
if bool(r.strip()):
check_list.append(r)
if not bool(row[order_group].strip()) and not check_list:
- continue
+ continue
- if line == 2:#Check for UTF-8 Format. Only for first line i.e. line=2.
- self._check_csv_format(row)
+# if line == 2:#Check for UTF-8 Format. Only for first line i.e. line=2.
+# self._check_csv_format(row)
error_line_vals = {'error_name' : '', 'error': False}
partner_value = row[partner_id].strip()
@@ -270,28 +296,28 @@ def import_sale_data(self):
error_line_vals['error'] = True
else:
self._get_partner_dict(partner_value, partner_dict, error_line_vals)
-
+
product_id_value = row[product_id].strip()
if not product_id_value:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Product is empty!') + '\n'
error_line_vals['error'] = True
else:
self._get_product_dict(product_id_value, product_dict, error_line_vals)
-
+
pricelist_value = row[pricelist_id].strip()
if not pricelist_value:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Pricelist is empty!') + '\n'
error_line_vals['error'] = True
else:
self._get_pricelist_dict(pricelist_value, pricelist_dict, error_line_vals)
-
+
warehouse_value = row[warehouse_id].strip()
if not warehouse_value:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Warehouse is empty!') + '\n'
error_line_vals['error'] = True
else:
self._get_picking_dict(warehouse_value, picking_dict, error_line_vals)
-
+
taxes = []
tax_from_chunk = row[taxes_id].strip()
if tax_from_chunk:
@@ -303,41 +329,44 @@ def import_sale_data(self):
error_line_vals['error'] = True
else:
qty = float(qty)
-
+
if qty <= 0:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Quantity not less than zero!') + '\n'
error_line_vals['error'] = True
-
+
price_unit_value = row[price_unit].strip()
if not price_unit_value:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Unit Price is empty!') + '\n'
error_line_vals['error'] = True
else:
price_unit_value = float(price_unit_value)
-
+
if price_unit_value <= 0:
error_line_vals['error_name'] = error_line_vals['error_name'] + _('Unit Price not less than zero!') + '\n'
error_line_vals['error'] = True
-
+
order_policy = self.order_policy
picking_policy = self.picking_policy
order = row[order_group].strip()
-
+
error_log_id = self._update_error_log(error_log_id, error_line_vals, ir_attachment, model, line, order)
-
+
if not error_log_id:
name = row[line_name].strip()
-
- product_data = self.env['sale.order.line'].product_id_change(pricelist_dict[pricelist_value], product_dict[product_id_value], qty, False, 0, False, '', partner_dict[partner_value],False, True, False, False, False, False)
+# product_data = self.env['sale.order.line'].product_id_change(pricelist_dict[pricelist_value], product_dict[product_id_value], qty, False, 0, False, '', partner_dict[partner_value],False, True, False, False, False, False)
+# product_data = self.env['sale.order.line'].product_id_change()
+ product_data = self.env['product.product'].browse(product_dict[product_id_value]) # odoo11
if not name:
name = product_data['value']['name']
+
state = 'draft'
if order not in order_item_dict.keys():
order_item_dict[order] = [{
'name' : name,
'product_id' : product_dict[product_id_value],
'product_uom_qty' : qty,
- 'product_uom' : product_data['value']['product_uom'],
+# 'product_uom' : product_data['value']['product_uom'], # odoo11
+ 'product_uom' : product_data.uom_id.id,
'price_unit' : price_unit_value,
'state' : state,
'tax_id':taxes,
@@ -347,28 +376,34 @@ def import_sale_data(self):
'name' : name,
'product_id' : product_dict[product_id_value],
'product_uom_qty' : qty,
- 'product_uom' : product_data['value']['product_uom'],
+# 'product_uom' : product_data['value']['product_uom'],# odoo11
+ 'product_uom' : product_data.uom_id.id,
'price_unit' : price_unit_value,
'state' : state,
'tax_id':taxes,
})
-
+
if order not in order_dict:
- pricelist_data = self.env['sale.order'].onchange_pricelist_id(pricelist_dict[pricelist_value], False)
- partner_data = self.env['sale.order'].onchange_partner_id(partner_dict[partner_value])
+# pricelist_data = self.env['sale.order'].onchange_pricelist_id(pricelist_dict[pricelist_value], False)
+# partner_data = self.env['sale.order'].onchange_partner_id(partner_dict[partner_value])
+ partner_data = self.env['res.partner'].browse(partner_dict[partner_value])
+ pricelist_data = partner_data.property_product_pricelist and partner_data.property_product_pricelist.id or False
+ addr = partner_data.address_get(['delivery', 'invoice'])
order_dict[order] = {
'partner_id' : partner_dict[partner_value],
- 'partner_invoice_id' : partner_data['value']['partner_invoice_id'],
+# 'partner_invoice_id' : partner_data['value']['partner_invoice_id'], # odoo11
+ 'partner_invoice_id' : addr['invoice'],
'pricelist_id' : pricelist_dict[pricelist_value],
'location_id': picking_dict[warehouse_value].default_location_dest_id and picking_dict[warehouse_value].default_location_dest_id.id,
- 'partner_shipping_id' : partner_data['value']['partner_shipping_id'],
- 'payment_term': partner_data['value']['payment_term'],
+# 'partner_shipping_id' : partner_data['value']['partner_shipping_id'], # odoo11
+ 'partner_shipping_id' : addr['delivery'],
+# 'payment_term': partner_data['value']['payment_term'], # odoo11
+ 'payment_term': partner_data.property_payment_term_id and partner_data.property_payment_term_id.id or False,
'order_policy' : order_policy,
'picking_policy': picking_policy,
- 'currency_id' : pricelist_data['value']['currency_id'],
+# 'currency_id' : pricelist_data['value']['currency_id'], # odoo11
'note': row[notes].strip()
}
-
if not error_log_id:
error_log_id = self.env['error.log'].create({'input_file': ir_attachment.id,
'import_user_id' : self.env.user.id,
@@ -382,74 +417,83 @@ def import_sale_data(self):
for so_line in order_item_dict[item]:
orderline_id = self._get_orderline_id(so_line, order_id)
- order_id.signal_workflow('order_confirm')
+# order_id.signal_workflow('order_confirm') # odoo11
+ order_id.action_confirm() # odoo11
if order_id.picking_ids:
for picking in order_id.picking_ids:
available = picking.action_assign()
- if order_id.order_policy == 'picking':
+# if order_id.order_policy == 'picking': # odoo11 TODO
+ if self.order_policy == 'picking': # TODO check now order policy removed from sale order it is on product
pass
#IF INVOICE POLICY IS FROM DELIVERY ORDER THEN WE WILL NOT CREATE INVOICE FROM HERE AND WE WILL PROCESS/CREATE INVOICE WHILE IMPORTING PICKINGS CSV. MEANS PICKING WILL BE HAVING STATE 2BINVOICED WILL BE PROCESS INVOICE/PAYMENT WHILE IMPORTING PICKING CSV.
#invoice = picking.action_invoice_create(
# journal_id = self.customer_invoice_journal_id.id,
# type = 'out_invoice'
# )
- if order_id.state == 'manual' or order_id.state == 'prepaid':
- invoice = order_id.signal_workflow('manual_invoice')
+
+# if order_id.state == 'manual' or order_id.state == 'prepaid':
+# invoice = order_id.signal_workflow('manual_invoice') # odoo 11
+
+ invoice_ids = order_id.action_invoice_create() # odoo11
+
if order_id.invoice_ids:
for invoice in order_id.invoice_ids:
invoice.journal_id = self.customer_invoice_journal_id.id
if invoice.state == 'draft':
- invoice.signal_workflow('invoice_open')
- if self.customer_payment_journal_id.currency and self.customer_payment_journal_id.currency.id != invoice.currency_id.id:
- currency_id_voucher = self.customer_payment_journal_id.currency.id
- voucher_amount = invoice.currency_id.compute(invoice.amount_total, self.customer_payment_journal_id.currency)
- elif not self.customer_payment_journal_id.currency and invoice.currency_id.id != invoice.company_id.currency_id.id:
- currency_id_voucher = invoice.company_id.currency_id.id
- voucher_amount = invoice.currency_id.compute(invoice.amount_total, invoice.company_id.currency_id)
- else:
- currency_id_voucher = invoice.currency_id.id
- voucher_amount = invoice.amount_total
- partner_data = self.env['account.voucher'].onchange_partner_id(invoice.partner_id.id,
- self.customer_payment_journal_id.id,
- voucher_amount,
- currency_id_voucher,
- 'receipt',
- invoice.date_invoice)
- journal_data = self.env['account.voucher'].onchange_journal_voucher(line_ids= False,
- tax_id=False,
- price=0.0,
- partner_id=invoice.partner_id.id,
- journal_id=self.customer_payment_journal_id.id,
- ttype='receipt',
- company_id=invoice.company_id.id)
- line_cr_list = []
- for line in partner_data['value']['line_cr_ids']:
- moveline = self.env['account.move.line'].browse(line['move_line_id'])
- if invoice.id == moveline.invoice.id:
- line['amount'] = voucher_amount
- line_cr_list.append((0, 0, line))
- break #IF one line found then get out of loop since invoice and payment has one to one relation.
- voucher_vals = {
- 'name': '/',
- 'partner_id' : invoice.partner_id.id,
- 'company_id' : invoice.company_id.id,
- 'journal_id' : self.customer_payment_journal_id.id,
- 'currency_id': currency_id_voucher,
- 'line_ids' : False,
- 'line_cr_ids' : line_cr_list,
- 'line_dr_ids' : False,
- 'account_id' : partner_data['value']['account_id'],
- 'period_id': journal_data['value']['period_id'],
- 'state': 'draft',
- 'date' : invoice.date_invoice,
- 'type': 'receipt',
- 'amount' : voucher_amount,
- 'payment_rate': journal_data['value']['payment_rate'],
- 'payment_rate_currency_id': journal_data['value']['payment_rate_currency_id']
- }
- voucher_id = self.env['account.voucher'].create(voucher_vals)
- voucher_id.signal_workflow('proforma_voucher')
-
+# invoice.signal_workflow('invoice_open')
+ invoice.action_invoice_open() # odoo11
+ invoice.pay_and_reconcile(self.customer_payment_journal_id.id) # odoo11
+
+ # no need to create manual payment we have odoo standard method to do this so just called it
+# if self.customer_payment_journal_id.currency and self.customer_payment_journal_id.currency.id != invoice.currency_id.id:
+# currency_id_voucher = self.customer_payment_journal_id.currency.id
+# voucher_amount = invoice.currency_id.compute(invoice.amount_total, self.customer_payment_journal_id.currency)
+# elif not self.customer_payment_journal_id.currency and invoice.currency_id.id != invoice.company_id.currency_id.id:
+# currency_id_voucher = invoice.company_id.currency_id.id
+# voucher_amount = invoice.currency_id.compute(invoice.amount_total, invoice.company_id.currency_id)
+# else:
+# currency_id_voucher = invoice.currency_id.id
+# voucher_amount = invoice.amount_total
+# partner_data = self.env['account.voucher'].onchange_partner_id(invoice.partner_id.id,
+# self.customer_payment_journal_id.id,
+# voucher_amount,
+# currency_id_voucher,
+# 'receipt',
+# invoice.date_invoice)
+# journal_data = self.env['account.voucher'].onchange_journal_voucher(line_ids= False,
+# tax_id=False,
+# price=0.0,
+# partner_id=invoice.partner_id.id,
+# journal_id=self.customer_payment_journal_id.id,
+# ttype='receipt',
+# company_id=invoice.company_id.id)
+# line_cr_list = []
+# for line in partner_data['value']['line_cr_ids']:
+# moveline = self.env['account.move.line'].browse(line['move_line_id'])
+# if invoice.id == moveline.invoice.id:
+# line['amount'] = voucher_amount
+# line_cr_list.append((0, 0, line))
+# break #IF one line found then get out of loop since invoice and payment has one to one relation.
+# voucher_vals = {
+# 'name': '/',
+# 'partner_id' : invoice.partner_id.id,
+# 'company_id' : invoice.company_id.id,
+# 'journal_id' : self.customer_payment_journal_id.id,
+# 'currency_id': currency_id_voucher,
+# 'line_ids' : False,
+# 'line_cr_ids' : line_cr_list,
+# 'line_dr_ids' : False,
+# 'account_id' : partner_data['value']['account_id'],
+# 'period_id': journal_data['value']['period_id'],
+# 'state': 'draft',
+# 'date' : invoice.date_invoice,
+# 'type': 'receipt',
+# 'amount' : voucher_amount,
+# 'payment_rate': journal_data['value']['payment_rate'],
+# 'payment_rate_currency_id': journal_data['value']['payment_rate_currency_id']
+# }
+# voucher_id = self.env['account.voucher'].create(voucher_vals)
+# voucher_id.signal_workflow('proforma_voucher')
res = self.env.ref('base_import_log.error_log_action')
res = res.read()[0]
res['domain'] = str([('id','in',[error_log_id])])
diff --git a/sale_order_import/wizard/import_sale_view.xml b/sale_order_import/wizard/import_sale_view.xml
index 318bd01..c66dda9 100644
--- a/sale_order_import/wizard/import_sale_view.xml
+++ b/sale_order_import/wizard/import_sale_view.xml
@@ -6,13 +6,14 @@
error.log
-
-
+
+
+
-
+