Add ShipmentCSVProductMixin and stock.csv_import model.
This commit refs #12215
This commit is contained in:
parent
11e4e33c7f
commit
7f9156c36b
|
@ -10,9 +10,15 @@ def register():
|
|||
Pool.register(
|
||||
configuration.Configuration,
|
||||
stock.CsvImportStart,
|
||||
stock.StockCsvImport,
|
||||
shipment.ShipmentOutReturn,
|
||||
shipment.ShipmentIn,
|
||||
module='stock_csv_import', type_='model')
|
||||
Pool.register(
|
||||
stock.CsvImport,
|
||||
module='stock_csv_import', type_='wizard')
|
||||
Pool.register(
|
||||
shipment.ShipmentOutReturnProduct,
|
||||
shipment.ShipmentInProduct,
|
||||
module='stock_csv_import', type_='model',
|
||||
depends=['product_cross_reference'])
|
||||
|
|
38
locale/es.po
38
locale/es.po
|
@ -46,6 +46,30 @@ msgctxt "field:stock.shipment.csv_import.start,delimiter:"
|
|||
msgid "Delimiter"
|
||||
msgstr "Delimitador"
|
||||
|
||||
msgctxt "field:stock.shipment.csv_import.start,store_file:"
|
||||
msgid "Store File"
|
||||
msgstr "Guardar fichero"
|
||||
|
||||
msgctxt "field:stock.shipment.csv_import.start,name:"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
msgctxt "field:stock.csv_import,name:"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
msgctxt "field:stock.csv_import,model:"
|
||||
msgid "Model"
|
||||
msgstr "Modelo"
|
||||
|
||||
msgctxt "field:stock.csv_import,date:"
|
||||
msgid "Date"
|
||||
msgstr "Fecha"
|
||||
|
||||
msgctxt "field:stock.csv_import,file:"
|
||||
msgid "File"
|
||||
msgstr "Fichero"
|
||||
|
||||
msgctxt "selection:stock.shipment.csv_import.start,shipment_type:"
|
||||
msgid "In"
|
||||
msgstr "Proveedor"
|
||||
|
@ -68,4 +92,16 @@ msgstr "Importar CSV albarán proveedor"
|
|||
|
||||
msgctxt "model:ir.ui.menu,name:menu_wizard_shipment_in_csv_import"
|
||||
msgid "Import CSV Shipment In"
|
||||
msgstr "Importar CSV proveedor"
|
||||
msgstr "Importar CSV proveedor"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_stock_csv_import"
|
||||
msgid "CSV Import"
|
||||
msgstr "Importaciones CSV"
|
||||
|
||||
msgctxt "model:ir.action,name:act_stock_csv_import"
|
||||
msgid "CSV Import"
|
||||
msgstr "Importaciones CSV"
|
||||
|
||||
msgctxt "view:stock.csv_import:"
|
||||
msgid "Time"
|
||||
msgstr "Hora"
|
12
setup.py
12
setup.py
|
@ -45,7 +45,13 @@ else:
|
|||
branch = series
|
||||
|
||||
dependency_links = {
|
||||
|
||||
'product_cross_reference':
|
||||
'git+https://gitlab.com/datalifeit/'
|
||||
'trytond-product_cross_reference@%(branch)s'
|
||||
'#egg=datalife_product_cross_reference-%(series)s' % {
|
||||
'branch': branch,
|
||||
'series': series,
|
||||
}
|
||||
}
|
||||
|
||||
requires = []
|
||||
|
@ -58,7 +64,9 @@ for dep in info.get('depends', []):
|
|||
requires.append(req)
|
||||
requires.append(get_require_version('trytond'))
|
||||
|
||||
tests_require = [get_require_version('proteus')]
|
||||
tests_require = [
|
||||
get_require_version('proteus'),
|
||||
'datalife_product_cross_reference']
|
||||
|
||||
dependency_links = list(dependency_links.values())
|
||||
if minor_version % 2:
|
||||
|
|
51
shipment.py
51
shipment.py
|
@ -1,9 +1,10 @@
|
|||
# The COPYRIGHT file at the top level of this repository contains the full
|
||||
# copyright notices and license terms.
|
||||
from trytond.pool import PoolMeta
|
||||
from .stock import ShipmentCSVMixin
|
||||
from .stock import ShipmentCSVMixin, ShipmentCSVProductMixin
|
||||
|
||||
__all__ = ['ShipmentOutReturn', 'ShipmentIn']
|
||||
__all__ = ['ShipmentOutReturn', 'ShipmentIn', 'ShipmentInProduct',
|
||||
'ShipmentOutReturnProduct']
|
||||
|
||||
|
||||
class ShipmentOutReturn(ShipmentCSVMixin, metaclass=PoolMeta):
|
||||
|
@ -52,3 +53,49 @@ class ShipmentIn(ShipmentCSVMixin, metaclass=PoolMeta):
|
|||
def _set_csv_move_locations(self, move):
|
||||
move.from_location = self.on_change_with_supplier_location()
|
||||
move.to_location = self.on_change_with_warehouse_input()
|
||||
|
||||
|
||||
class ShipmentOutReturnProduct(ShipmentCSVProductMixin, metaclass=PoolMeta):
|
||||
__name__ = 'stock.shipment.out.return'
|
||||
|
||||
@classmethod
|
||||
def _get_cross_reference_domain(cls, data):
|
||||
domain = super()._get_cross_reference_domain(data)
|
||||
subdomain = ['OR',
|
||||
[
|
||||
('party', '=', data['customer'].id),
|
||||
('address', '=', None)],
|
||||
[
|
||||
('party', '=', None),
|
||||
('address', '=', None)]
|
||||
]
|
||||
if ('delivery_address' in data.keys() and data['delivery_address']):
|
||||
subdomain.append([
|
||||
('party', '=', data['customer'].id),
|
||||
('address', '=', data['delivery_address'].id)
|
||||
])
|
||||
domain.append(subdomain)
|
||||
return domain
|
||||
|
||||
|
||||
class ShipmentInProduct(ShipmentCSVProductMixin, metaclass=PoolMeta):
|
||||
__name__ = 'stock.shipment.in'
|
||||
|
||||
@classmethod
|
||||
def _get_cross_reference_domain(cls, data):
|
||||
domain = super()._get_cross_reference_domain(data)
|
||||
subdomain = ['OR',
|
||||
[
|
||||
('party', '=', data['supplier'].id),
|
||||
('address', '=', None)],
|
||||
[
|
||||
('party', '=', None),
|
||||
('address', '=', None)]
|
||||
]
|
||||
if ('contact_address' in data.keys() and data['contact_address']):
|
||||
subdomain.append([
|
||||
('party', '=', data['supplier'].id),
|
||||
('address', '=', data['contact_address'].id)
|
||||
])
|
||||
domain.append(subdomain)
|
||||
return domain
|
||||
|
|
125
stock.py
125
stock.py
|
@ -6,7 +6,7 @@ import tempfile
|
|||
from datetime import datetime
|
||||
from collections import OrderedDict
|
||||
from trytond.pool import Pool
|
||||
from trytond.model import fields, ModelView
|
||||
from trytond.model import fields, ModelView, ModelSQL
|
||||
from trytond.pyson import Eval, Not, Bool
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import Wizard, StateView, StateAction, Button
|
||||
|
@ -17,7 +17,17 @@ from trytond.config import config
|
|||
from os import path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
__all__ = ['ShipmentCSVMixin', 'CsvImport', 'CsvImportStart']
|
||||
__all__ = ['ShipmentCSVMixin', 'CsvImport', 'CsvImportStart', 'StockCsvImport',
|
||||
'ShipmentCSVProductMixin']
|
||||
|
||||
|
||||
if config.getboolean('stock_csv_import', 'filestore', default=True):
|
||||
file_id = 'file_id'
|
||||
store_prefix = config.get('stock_csv_import', 'store_prefix',
|
||||
default=None)
|
||||
else:
|
||||
file_id = None
|
||||
store_prefix = None
|
||||
|
||||
|
||||
class ShipmentCSVMixin(object):
|
||||
|
@ -40,7 +50,7 @@ class ShipmentCSVMixin(object):
|
|||
|
||||
@classmethod
|
||||
def _get_csv_field_value(cls, Model, field_name, field_value,
|
||||
data=None, row=[]):
|
||||
data=None, row=[], user_error=True):
|
||||
pool = Pool()
|
||||
splitted_field = []
|
||||
if '.' in field_name:
|
||||
|
@ -58,7 +68,7 @@ class ShipmentCSVMixin(object):
|
|||
else:
|
||||
domain.append(('rec_name', '=', field_value))
|
||||
value = RelModel.search(domain)
|
||||
if field_value and not value:
|
||||
if user_error and field_value and not value:
|
||||
cls.raise_user_error('csv_relation_not_found', (
|
||||
Model.fields_get(fields_names=[fieldname]
|
||||
)[fieldname]['string'],
|
||||
|
@ -86,13 +96,17 @@ class ShipmentCSVMixin(object):
|
|||
return headers or []
|
||||
|
||||
@classmethod
|
||||
def import_csv(cls, csv_file, csv_delimiter=','):
|
||||
def import_csv(cls, csv_file, csv_delimiter=',', name=None,
|
||||
store_file=False):
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
Move = pool.get('stock.move')
|
||||
CsvImport = pool.get('stock.csv_import')
|
||||
Model = pool.get('ir.model')
|
||||
old_shipment = None
|
||||
to_del = []
|
||||
shipments = []
|
||||
file = csv_file
|
||||
|
||||
config_header = cls._get_csv_headers()
|
||||
|
||||
|
@ -161,7 +175,7 @@ class ShipmentCSVMixin(object):
|
|||
effective_date=shipment.effective_date)
|
||||
for move_key, move_value in move_values.items():
|
||||
_value = cls._get_csv_field_value(
|
||||
Move, move_key, move_value)
|
||||
Move, move_key, move_value, data=v)
|
||||
move_field = move_key.split('.')[0]
|
||||
setattr(move, move_field, _value)
|
||||
shipment._set_csv_move_locations(move)
|
||||
|
@ -177,6 +191,13 @@ class ShipmentCSVMixin(object):
|
|||
shipment.incoming_moves = list(
|
||||
shipment.incoming_moves) + moves
|
||||
|
||||
if store_file:
|
||||
model, = Model.search([('model', '=', cls.__name__)])
|
||||
csv_import = CsvImport(
|
||||
name=name,
|
||||
model=model,
|
||||
file=file)
|
||||
csv_import.save()
|
||||
if shipments:
|
||||
cls.save(shipments)
|
||||
if to_del:
|
||||
|
@ -260,6 +281,60 @@ class ShipmentCSVMixin(object):
|
|||
os.path.join(folder_path, 'backup', filename))
|
||||
|
||||
|
||||
class ShipmentCSVProductMixin(object):
|
||||
|
||||
@classmethod
|
||||
def _get_cross_reference_model(cls, relation):
|
||||
pool = Pool()
|
||||
relation = relation.split('.')[0] + '.cross_reference'
|
||||
return pool.get(relation)
|
||||
|
||||
@classmethod
|
||||
def _get_cross_reference_domain(cls, data):
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def _get_csv_field_value(cls, Model, field_name, field_value,
|
||||
data=None, row=[], user_error=True):
|
||||
if '.' in field_name:
|
||||
splitted_field = field_name.split('.')
|
||||
fieldname = splitted_field[0]
|
||||
else:
|
||||
fieldname = field_name
|
||||
if fieldname == 'product':
|
||||
user_error = False
|
||||
|
||||
value = super()._get_csv_field_value(Model, field_name, field_value,
|
||||
data=data, row=row, user_error=user_error)
|
||||
|
||||
if isinstance(Model._fields[fieldname], fields.Many2One):
|
||||
field = Model._fields[fieldname]
|
||||
relation = field.get_target().__name__
|
||||
|
||||
if relation == 'product.product' and not value:
|
||||
if not splitted_field or (splitted_field and
|
||||
splitted_field[1] in ('name', 'code')):
|
||||
CrossReference = cls._get_cross_reference_model(relation)
|
||||
domain = cls._get_cross_reference_domain(data)
|
||||
if splitted_field:
|
||||
domain.append((splitted_field[1], '=', field_value))
|
||||
else:
|
||||
domain.append(('rec_name', '=', field_value))
|
||||
cross_reference = CrossReference.search(domain,
|
||||
order=[
|
||||
('party', 'ASC NULLS LAST'),
|
||||
('address', 'ASC NULLS LAST')])
|
||||
if not cross_reference:
|
||||
cls.raise_user_error('csv_relation_not_found', (
|
||||
Model.fields_get(fields_names=[fieldname]
|
||||
)[fieldname]['string'],
|
||||
field_value))
|
||||
return (cross_reference[0].product
|
||||
if cross_reference else None)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class CsvImport(Wizard):
|
||||
"""Shipment CSV Import"""
|
||||
__name__ = 'stock.shipment.csv_import'
|
||||
|
@ -297,12 +372,21 @@ class CsvImport(Wizard):
|
|||
Shipment = pool.get(self.start.shipment_type)
|
||||
csv_file = self.start.csv_file
|
||||
return Shipment.import_csv(csv_file,
|
||||
csv_delimiter=str(self.start.delimiter))
|
||||
csv_delimiter=str(self.start.delimiter),
|
||||
name=self.start.name, store_file=self.start.store_file)
|
||||
|
||||
def do_import_(self, action):
|
||||
pool = Pool()
|
||||
ModelData = pool.get('ir.model.data')
|
||||
Action = pool.get('ir.action')
|
||||
|
||||
shipments = self._do_import()
|
||||
|
||||
action_id = Action.get_action_id(ModelData.get_id('stock',
|
||||
'act_%s_form' % self.start.shipment_type[6:].replace('.', '_')))
|
||||
action = Action(action_id)
|
||||
data = {'res_id': [i.id for i in shipments] or []}
|
||||
return action, data
|
||||
return Action.get_action_values(action.type, [action.id])[0], data
|
||||
|
||||
def _get_model(self):
|
||||
pass
|
||||
|
@ -324,7 +408,32 @@ class CsvImportStart(ModelView):
|
|||
delimiter = fields.Selection([
|
||||
(',', ','),
|
||||
(';', ';')], 'Delimiter', required=True)
|
||||
store_file = fields.Boolean('Store File')
|
||||
name = fields.Char('Name',
|
||||
states={
|
||||
'required': Bool(Eval('store_file'))},
|
||||
depends=['store_file'])
|
||||
|
||||
@staticmethod
|
||||
def default_delimiter():
|
||||
return ','
|
||||
|
||||
@staticmethod
|
||||
def default_store_file():
|
||||
return True
|
||||
|
||||
|
||||
class StockCsvImport(ModelSQL, ModelView):
|
||||
"""Import CSV"""
|
||||
__name__ = 'stock.csv_import'
|
||||
|
||||
name = fields.Char('Name', required=True)
|
||||
model = fields.Many2One('ir.model', 'Model', required=True, domain=[
|
||||
('model', 'in', ['stock.shipment.in', 'stock.shipment.out.return'])])
|
||||
date = fields.Function(fields.Date('Date'), 'get_date')
|
||||
file = fields.Binary('File', required=True, readonly=True,
|
||||
file_id=file_id, store_prefix=store_prefix)
|
||||
file_id = fields.Char('File ID', readonly=True)
|
||||
|
||||
def get_date(self, name):
|
||||
return self.create_date
|
||||
|
|
27
stock.xml
27
stock.xml
|
@ -16,5 +16,32 @@
|
|||
<field name="type">form</field>
|
||||
<field name="name">shipment_csv_import_form</field>
|
||||
</record>
|
||||
|
||||
<!-- Stock CSV Import -->
|
||||
<record model="ir.ui.view" id="stock_csv_import_view_list">
|
||||
<field name="model">stock.csv_import</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="name">stock_csv_import_list</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="stock_csv_import_view_form">
|
||||
<field name="model">stock.csv_import</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">stock_csv_import_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_stock_csv_import">
|
||||
<field name="name">CSV Import</field>
|
||||
<field name="res_model">stock.csv_import</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_stock_csv_import_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="stock_csv_import_view_list"/>
|
||||
<field name="act_window" ref="act_stock_csv_import"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_stock_csv_import_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="stock_csv_import_view_form"/>
|
||||
<field name="act_window" ref="act_stock_csv_import"/>
|
||||
</record>
|
||||
<menuitem parent="stock.menu_configuration" action="act_stock_csv_import" id="menu_stock_csv_import" icon="tryton-list"/>
|
||||
</data>
|
||||
</tryton>
|
|
@ -0,0 +1,2 @@
|
|||
reference,supplier,contact_address,warehouse,effective_date,product,quantity
|
||||
Reference 1,Supplier,Street 1,Warehouse 1,2016-09-20,Product Error,1
|
|
|
@ -0,0 +1,2 @@
|
|||
reference,supplier,contact_address,warehouse,effective_date,product,quantity
|
||||
Reference 1,Supplier,Street 1,Warehouse 1,2016-09-20,Product Ref 2,1
|
|
|
@ -0,0 +1,2 @@
|
|||
reference,customer,zip_customer,effective_date,warehouse,product,quantity
|
||||
15,IT00972990709,86020,2019-01-14,WH,Product Ref 1,20
|
|
|
@ -0,0 +1,176 @@
|
|||
===========================================
|
||||
Product Cross Reference CSV Import Scenario
|
||||
===========================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.tests.tools import activate_modules
|
||||
>>> from trytond.modules.stock_csv_import.tests.tools import read_csv_file
|
||||
>>> import os
|
||||
>>> from trytond.modules.company.tests.tools import create_company, \
|
||||
... get_company
|
||||
>>> from decimal import Decimal
|
||||
>>> import datetime
|
||||
>>> today = datetime.date.today()
|
||||
|
||||
Install stock_csv_import::
|
||||
|
||||
>>> config = activate_modules(['stock_csv_import', 'product_cross_reference'])
|
||||
|
||||
Create company::
|
||||
|
||||
>>> _ = create_company()
|
||||
>>> company = get_company()
|
||||
|
||||
Create Configuration::
|
||||
|
||||
>>> Configuration = Model.get('stock.configuration')
|
||||
>>> config = Configuration()
|
||||
>>> config.shipment_out_return_csv_headers = "reference,customer.tax_identifier.code,delivery_address.zip,effective_date,warehouse.code,incoming_moves.product.name,incoming_moves.quantity"
|
||||
>>> config.shipment_in_csv_headers = "reference,supplier.name,contact_address,warehouse.name,effective_date,incoming_moves.product.name,incoming_moves.quantity"
|
||||
>>> config.save()
|
||||
|
||||
Create Parties::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> customer = Party(name='Customer')
|
||||
>>> customer.save()
|
||||
>>> customer.addresses[0].zip = '86020'
|
||||
>>> customer.save()
|
||||
>>> identifier = customer.identifiers.new()
|
||||
>>> identifier.code = 'IT00972990709'
|
||||
>>> identifier.type = 'eu_vat'
|
||||
>>> customer.save()
|
||||
>>> supplier = Party(name='Supplier')
|
||||
>>> address, = supplier.addresses
|
||||
>>> address.street = 'Street 1'
|
||||
>>> supplier.save()
|
||||
|
||||
Create Products::
|
||||
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> Product = Model.get('product.product')
|
||||
>>> product1 = Product()
|
||||
>>> product2 = Product()
|
||||
>>> template1 = ProductTemplate()
|
||||
>>> template1.name = 'Product 1'
|
||||
>>> template1.default_uom = unit
|
||||
>>> template1.type = 'goods'
|
||||
>>> template1.purchasable = True
|
||||
>>> template1.list_price = Decimal('10')
|
||||
>>> template1.cost_price = Decimal('5')
|
||||
>>> template1.cost_price_method = 'fixed'
|
||||
>>> template1.save()
|
||||
>>> product1.template = template1
|
||||
>>> product1.save()
|
||||
>>> template2 = ProductTemplate()
|
||||
>>> template2.name = 'Product 2'
|
||||
>>> template2.default_uom = unit
|
||||
>>> template2.type = 'goods'
|
||||
>>> template2.purchasable = True
|
||||
>>> template2.list_price = Decimal('10')
|
||||
>>> template2.cost_price = Decimal('5')
|
||||
>>> template2.cost_price_method = 'fixed'
|
||||
>>> template2.save()
|
||||
>>> product2.template = template2
|
||||
>>> product2.save()
|
||||
|
||||
Create Product Cross Reference::
|
||||
|
||||
>>> CrossReference = Model.get('product.cross_reference')
|
||||
>>> cross_reference = CrossReference()
|
||||
>>> cross_reference.party = customer
|
||||
>>> cross_reference.product = product1
|
||||
>>> cross_reference.name = 'Product Ref 1'
|
||||
>>> cross_reference.save()
|
||||
>>> cross_reference2 = CrossReference()
|
||||
>>> cross_reference2.party = supplier
|
||||
>>> cross_reference2.product = product2
|
||||
>>> cross_reference2.name = 'Product Ref 2'
|
||||
>>> cross_reference2.save()
|
||||
|
||||
|
||||
CSV import shipment out return wizard::
|
||||
|
||||
>>> ShipmentOutReturn = Model.get('stock.shipment.out.return')
|
||||
>>> Data = Model.get('ir.model.data')
|
||||
>>> data, = Data.find([
|
||||
... ('module', '=', 'stock_csv_import'),
|
||||
... ('fs_id', '=', 'wizard_shipment_out_return_csv_import')])
|
||||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__),
|
||||
... 'product_cross_reference_out_return.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.form.store_file = False
|
||||
>>> csv_import.execute('import_')
|
||||
>>> shipment, = ShipmentOutReturn.find([])
|
||||
>>> move, = shipment.moves
|
||||
>>> move.product == product1
|
||||
True
|
||||
|
||||
Get stock locations::
|
||||
|
||||
>>> Location = Model.get('stock.location')
|
||||
>>> lost_found_loc, = Location.find([('type', '=', 'lost_found')])
|
||||
>>> storage_loc, = Location.find([('code', '=', 'STO')])
|
||||
>>> internal_loc = Location(name='Internal', type='storage')
|
||||
>>> internal_loc.save()
|
||||
>>> warehouse_loc, = Location.find([('code', '=', 'WH')])
|
||||
>>> warehouse_loc.name = 'Warehouse 1'
|
||||
>>> warehouse_loc.save()
|
||||
|
||||
Create Move::
|
||||
|
||||
>>> Move = Model.get('stock.move')
|
||||
>>> move = Move()
|
||||
>>> move.product = product1
|
||||
>>> move.quantity = 1
|
||||
>>> move.from_location = internal_loc
|
||||
>>> move.to_location = storage_loc
|
||||
>>> move.currency = company.currency
|
||||
>>> move.save()
|
||||
|
||||
Create Shipment In::
|
||||
|
||||
>>> ShipmentIn = Model.get('stock.shipment.in')
|
||||
>>> shipment_in = ShipmentIn()
|
||||
>>> shipment_in.effective_date = today
|
||||
>>> shipment_in.supplier = supplier
|
||||
>>> shipment_in.warehouse = warehouse_loc
|
||||
>>> shipment_in.reference = 'Reference 1'
|
||||
>>> shipment_in.company = company
|
||||
>>> shipment_in.moves.append(move)
|
||||
>>> shipment_in.save()
|
||||
>>> len(shipment_in.moves)
|
||||
1
|
||||
|
||||
CSV import shipment in wizard::
|
||||
|
||||
>>> data, = Data.find([
|
||||
... ('module', '=', 'stock_csv_import'),
|
||||
... ('fs_id', '=', 'wizard_shipment_in_csv_import')])
|
||||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__),
|
||||
... 'product_cross_reference_in.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.form.store_file = False
|
||||
>>> csv_import.execute('import_')
|
||||
>>> shipment_in.reload()
|
||||
>>> len(shipment_in.moves)
|
||||
2
|
||||
>>> shipment_in.moves[0].product == product2
|
||||
True
|
||||
|
||||
When product cross reference does not exist::
|
||||
|
||||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__),
|
||||
... 'product_cross_reference_error.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.execute('import_')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
trytond.exceptions.UserError: Cannot find a Product record with value "Product Error". -
|
|
@ -108,6 +108,7 @@ Execute Wizard::
|
|||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__), 'in.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.form.name = 'CSV Import 1'
|
||||
>>> csv_import.execute('import_')
|
||||
>>> shipment_in.reload()
|
||||
>>> shipment_in.effective_date
|
||||
|
@ -117,10 +118,26 @@ Execute Wizard::
|
|||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__), 'in.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.form.store_file = False
|
||||
>>> csv_import.execute('import_')
|
||||
>>> len(Move.find())
|
||||
5
|
||||
|
||||
Check Stock CSV Import::
|
||||
|
||||
>>> IrModel = Model.get('ir.model')
|
||||
>>> model, = IrModel.find([('model', '=', 'stock.shipment.in')])
|
||||
>>> CsvImport = Model.get('stock.csv_import')
|
||||
>>> csv_import, = CsvImport.find([])
|
||||
>>> csv_import.name
|
||||
'CSV Import 1'
|
||||
>>> csv_import.model == model
|
||||
True
|
||||
>>> csv_import.file == read_csv_file(filename)
|
||||
True
|
||||
>>> csv_import.date == today
|
||||
True
|
||||
|
||||
When product does not exist::
|
||||
|
||||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
|
|
|
@ -11,6 +11,8 @@ Imports::
|
|||
>>> from trytond.modules.company.tests.tools import create_company, \
|
||||
... get_company
|
||||
>>> from decimal import Decimal
|
||||
>>> import datetime
|
||||
>>> today = datetime.date.today()
|
||||
|
||||
Install stock_csv_import::
|
||||
|
||||
|
@ -69,6 +71,7 @@ CSV import wizard::
|
|||
>>> csv_import = Wizard('stock.shipment.csv_import', action={'id': data.db_id})
|
||||
>>> filename = os.path.join(os.path.dirname(__file__), 'out_return.csv')
|
||||
>>> csv_import.form.csv_file = read_csv_file(filename)
|
||||
>>> csv_import.form.name = 'CSV Import 1'
|
||||
>>> csv_import.execute('import_')
|
||||
>>> shipment, = ShipmentOutReturn.find([])
|
||||
>>> shipment.effective_date
|
||||
|
@ -86,6 +89,21 @@ CSV import wizard::
|
|||
>>> move.product.name
|
||||
'Product 1'
|
||||
|
||||
Check Stock CSV Import::
|
||||
|
||||
>>> IrModel = Model.get('ir.model')
|
||||
>>> model, = IrModel.find([('model', '=', 'stock.shipment.out.return')])
|
||||
>>> CsvImport = Model.get('stock.csv_import')
|
||||
>>> csv_import, = CsvImport.find([])
|
||||
>>> csv_import.name
|
||||
'CSV Import 1'
|
||||
>>> csv_import.model == model
|
||||
True
|
||||
>>> csv_import.file == read_csv_file(filename)
|
||||
True
|
||||
>>> csv_import.date == today
|
||||
True
|
||||
|
||||
CSV import wizard when product does not exist::
|
||||
|
||||
>>> ShipmentOutReturn = Model.get('stock.shipment.out.return')
|
||||
|
|
|
@ -29,4 +29,9 @@ def suite():
|
|||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_product_cross_reference_csv_import.rst',
|
||||
tearDown=doctest_teardown, encoding='utf-8',
|
||||
checker=doctest_checker,
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
return suite
|
||||
|
|
|
@ -5,6 +5,9 @@ depends:
|
|||
res
|
||||
stock
|
||||
|
||||
extras_depend:
|
||||
product_cross_reference
|
||||
|
||||
xml:
|
||||
stock.xml
|
||||
shipment.xml
|
||||
|
|
|
@ -8,4 +8,8 @@
|
|||
<field name="delimiter"/>
|
||||
<label name="csv_file"/>
|
||||
<field name="csv_file"/>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="store_file"/>
|
||||
<field name="store_file"/>
|
||||
</form>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<form>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="model"/>
|
||||
<field name="model"/>
|
||||
<label name="file"/>
|
||||
<field name="file"/>
|
||||
</form>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- The COPYRIGHT file at the top level of this repository contains the full
|
||||
copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
<field name="date" widget="date"/>
|
||||
<field name="date" widget="time" string="Time"/>
|
||||
</tree>
|
Loading…
Reference in New Issue