"""
Create the records for moving an object in the :doc:`/workflow/stock_move/stock_move` flow.
"""
from datetime import datetime
import os
import configparser
# call the function "get_settings_odoo" to get the parameter
# for the logging of the model on the "odoo Webservice API"
try:
from .get_settings_odoo import get_settings_odoo
except ImportError:
from get_settings_odoo import get_settings_odoo
settings = get_settings_odoo()
db = settings[0]
uid = settings[1]
odoo_password = settings[3]
models = settings[4]
# ------- get all the global parameter from the settings file "parameter_global.ini"
# Name and full path of the "ini" file
filename = "parameter_global.ini"
path_name = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Go up to repo root
config_path = os.path.join(path_name, 'config')
fullpath = os.path.join(config_path, filename)
config = configparser.ConfigParser()
config.read(fullpath)
# get the default company id
custom_company_id = int(config.get('general_settings', 'company_id'))
# get the default currency of the company
custom_currency_id = config.get('general_settings', 'currency_id')
# the datasets will be stored with the user_id of the Batchuser
custom_create_uid = config.get('general_settings', 'Batchuser')
custom_write_uid = custom_create_uid
# ------- get all the parameters from the file "parameter_inventory.ini"
# ------- the section "create_order" of the Parameter File "parameter_inventory.ini" will be used
# Name and full path of the "ini" file
filename = "parameter_inventory.ini"
path_name = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Go up to repo root
config_path = os.path.join(path_name, 'config')
fullpath = os.path.join(config_path, filename)
config = configparser.ConfigParser()
config.read(fullpath)
# get the default warehouse id
custom_warehouse_id = int(config.get('create_order', 'warehouse_id'))
# get the default move type
custom_move_type = config.get('create_order', 'move_type')
# get the default state of the sale order
custom_sale_order_state = config.get('create_order', 'sale_order_state')
# get the default invoice status of the sale order
custom_sale_order_invoice_status = config.get('create_order', 'sale_order_invoice_status')
# get the default state of the procurement order
custom_procurement_order_state = config.get('create_order', 'procurement_order_state')
# get the default state of the stock move
custom_stock_move_state = config.get('create_order', 'stock_move_state')
# get the default CRM team
custom_crm_team = config.get('create_order', 'crm_team')
# get the default Unit of Measure of the Product
custom_product_uom = config.get('create_order', 'product_uom')
# get the default Product Quantity
custom_product_qty = config.get('create_order', 'product_qty')
# get the default payment term for the Invoice
custom_payment_term_id = config.get('create_order', 'payment_term_id')
# ------- get all the parameters from the file "parameter_inventory.ini"
# ------- the section "stock_move" of the Parameter File "parameter_inventory.ini" will be used
# get the maximum number of different transfer types
custom_max_number = int(config.get('stock_move', 'max_number_transfer_type'))
# initialize the different list variables
custom_transfer_name = []
custom_shortcut = []
custom_full_name = []
custom_location_source = []
custom_location_dest = []
custom_pricelist = []
custom_place = []
# these parameters are used to store data sets in the logistics tables of the database
i = 0
while i <= custom_max_number:
custom_string = str(i) + '_custom_transfer_name'
custom_transfer_name.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_shortcut'
custom_shortcut.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_full_name'
custom_full_name.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_location_source'
custom_location_source.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_location_dest'
custom_location_dest.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_pricelist'
custom_pricelist.append(config.get('stock_move', custom_string))
custom_string = str(i) + '_place'
custom_place.append(config.get('stock_move', custom_string))
i = i + 1
# ------- end of the initialisation
[docs]
def create_order(product_id, transfer):
"""
The function creates the main datasets during the move
of a product from one location to another:
- Stock Move
- Stock Picking
- Procurement Group
- Sales Order
- Account Move
3 main operations are execucuted in Odoo:
- create a sales order in the "Sales" module
- create the corresponding stock move in the "Inventory" module
- create the corresponding invoice in the "Accounting" module
Parameter:
- "product_id": product of the customer which will be moved
- "transfer": type of transfer to be used
"""
# Initial value as an indicator for the correctness of the value "transfer"
transfer_name = ''
i = 0
while i <= int(custom_max_number):
# if the correct transfer type has been found
# fill up the values with the corresponding parameter from the transfer type
if custom_transfer_name [i] == transfer:
transfer_name = custom_full_name [i]
custom_location_source_id = custom_location_source [i]
custom_location_dest_id = custom_location_dest [i]
custom_pricelist_id = custom_pricelist [i]
custom_x_place = custom_place [i]
i = i + 1
# test if a valid "transfer" value has been given with by the value "transfer_name"
if transfer_name != '':
# find the partner_id of the product
# first read the table "product.product" to find the corresponding data set
product_data = models.execute_kw(db, uid, odoo_password, 'product.product', 'search_read',
[[['id', '=', product_id]]],
{'fields': [ 'x_partner_id']})
# second get the partner_id of the product
for key, value in list(product_data[0].items()):
if key == "x_partner_id":
custom_partner_id = value[0]
# get the actual date and time for some values to store in the odoo database table
now = datetime.now()
custom_actual_date = now.strftime("%Y-%m-%d %H:%M:%S")
# create a "meaningful" name based on different values
transfer_name = str(custom_partner_id) + ' ' + str(product_id) + ' ' + transfer_name
# calculate the price of the transfer of the product
# find the price from the pricelist
# the valid pricelist is in between the actual date (parameter "date_start" and "date_end")
product_pricelist_item = models.execute_kw(db, uid, odoo_password, 'product.pricelist.item', 'search_read',
# [[['pricelist_id', '=', int(custom_pricelist_id)]]],
[[
'|',
['date_end', '>', custom_actual_date],
['date_end', '=', False],
['date_start', '<', custom_actual_date],
['pricelist_id', '=', int(custom_pricelist_id)],
['active', '=', 1], # == TRUE
]],
{'fields': ['date_start', 'date_end', 'fixed_price']})
# get the amount from the valid pricelist
for key, value in list(product_pricelist_item[0].items()):
if key == "fixed_price":
custom_fixed_price = value
# create a new sale_order record in the odoo table "sale_order"
custom_sale_order_id = models.execute_kw(db,uid, odoo_password,'sale.order', 'create',
[{
'company_id': int(custom_company_id),
'create_date': custom_actual_date,
'create_uid': custom_create_uid,
'currency_id': int(custom_currency_id),
'date_order': custom_actual_date,
'partner_id': custom_partner_id,
'payment_term_id': int(custom_payment_term_id),
'pricelist_id': int(custom_pricelist_id),
'team_id': int(custom_crm_team),
'state': custom_sale_order_state,
'invoice_status': custom_sale_order_invoice_status,
'warehouse_id': custom_warehouse_id,
}])
# create a new sale_order_line record in the odoo table "sale_order_line"; relating to the newly created sale_order record above
custom_sale_order_line_id = models.execute_kw(db,uid, odoo_password,'sale.order.line', 'create',
[{
'company_id': int(custom_company_id),
'create_date': custom_actual_date,
'create_uid': custom_create_uid,
'currency_id': int(custom_currency_id),
'order_partner_id': custom_partner_id,
'product_id': int(product_id),
'product_uom': int(custom_product_uom),
'product_uom_qty': float(custom_product_qty),
'qty_delivered': float(custom_product_qty),
'order_id': custom_sale_order_id,
'state': custom_sale_order_state,
'invoice_status': custom_sale_order_invoice_status,
}])
# update the sale order with a meaningful name
models.execute_kw(db,uid, odoo_password, 'sale.order', 'write',
[[custom_sale_order_id],
{'name': 'SO' + str(custom_sale_order_id) + ' ' + transfer_name,
}])
# update the sale order line with a meaningful name
models.execute_kw(db,uid, odoo_password, 'sale.order.line', 'write',
[[custom_sale_order_line_id],
{'name': 'SOL' + str(custom_sale_order_line_id) + ' ' + transfer_name,
}])
# automatically with the creating of the sale order, a procurement group record and a stock picking record have been stored
# the values of the procurement group record and the stock picking record will be updated
# find the corresponding procurement group record to the above created sale order record
procurement_group = models.execute_kw(db, uid, odoo_password, 'procurement.group', 'search',
[[['sale_id', '=', custom_sale_order_id]]])
custom_procurement_group_id = procurement_group[0]
# update the procurement group record
models.execute_kw(db,uid, odoo_password, 'procurement.group', 'write',
[[custom_procurement_group_id],
{
'name': 'PG' + str(custom_procurement_group_id) + ' ' + transfer_name,
'move_type': custom_move_type,
}])
# find the corresponding stock picking record to the above created sale order line by the procurement_group_id
stock_picking = models.execute_kw(db, uid, odoo_password, 'stock.picking', 'search',
[[['group_id', '=', custom_procurement_group_id]]])
custom_stock_picking_id = stock_picking[0]
# update the status of the stock picking record to "Validate"
action = models.execute_kw(db, uid, odoo_password, 'stock.picking', 'button_validate', [custom_stock_picking_id])
# create a stock imediate transfer record for the transfer of the product
custom_stock_immediate_transfer_id = models.execute_kw(db,uid, odoo_password,'stock.immediate.transfer', 'create',
[{
'pick_ids': [(6, 0, [custom_stock_picking_id])],
'show_transfers': 0, # == FALSE
}])
# create a the corresponding stock immediate transfer line record for the transfer of the product
models.execute_kw(db,uid, odoo_password,'stock.immediate.transfer.line', 'create',
[{
'picking_id': custom_stock_picking_id,
'immediate_transfer_id': custom_stock_immediate_transfer_id,
'to_immediate': 1, # == TRUE
}])
# update the status of the stock immediate transfer record to process the transfer
models.execute_kw(db, uid, odoo_password, 'stock.immediate.transfer', 'process', [custom_stock_immediate_transfer_id], {'context': action['context']})
# update the stock picking record
models.execute_kw(db,uid, odoo_password, 'stock.picking', 'write',
[[custom_stock_picking_id],
{
'location_id': int(custom_location_source_id),
'location_dest_id': int(custom_location_dest_id),
'name': 'SP' + str(custom_stock_picking_id) + ' ' + transfer_name,
'origin': 'SO' + str(custom_sale_order_id) + ' ' + transfer_name,
'move_type': custom_move_type,
'partner_id': custom_partner_id,
}])
# automatically with the creating of the sale order, a stock move order has been stored
# the values of the stock move order will be updated
# also two "stock_quant" records will be created, one for the deliver location and the other for the receiving location
# find the corresponding stock move order to the above procurement order
stock_move_id = models.execute_kw(db, uid, odoo_password, 'stock.move', 'search',
[[['group_id', '=', custom_procurement_group_id]]])
custom_stock_move_id = stock_move_id[0]
# update the stock move record
models.execute_kw(db,uid, odoo_password, 'stock.move', 'write',
[[custom_stock_move_id],
{
'name': 'SM' + str(custom_stock_move_id) + ' ' + transfer_name,
}])
# store a record in the odoo table "stock_quant" for the move from the deliver location
models.execute_kw(db,uid, odoo_password,'stock.quant', 'create',
[{
'location_id': int(custom_location_source_id),
'company_id': int(custom_company_id),
'create_uid': custom_create_uid,
'write_uid': custom_write_uid,
'in_date': custom_actual_date,
'product_id': int(product_id),
'owner_id': custom_partner_id,
'quantity': -1 * float(custom_product_qty),
}])
# store a record in the odoo table "stock_quant" for the move to the receiving location
models.execute_kw(db,uid, odoo_password,'stock.quant', 'create',
[{
'location_id': int(custom_location_dest_id),
'company_id': int(custom_company_id),
'create_uid': custom_create_uid,
'write_uid': custom_write_uid,
'in_date': custom_actual_date,
'product_id': int(product_id),
'owner_id': custom_partner_id,
'quantity': float(custom_product_qty),
}])
# update the product model
# the ("virtual") place of the object will be updated corresponding to the location of the product
models.execute_kw(db,uid, odoo_password, 'product.product', 'write',
[[int(product_id)],
{'x_place': custom_x_place}])
# update the sale order line record with the delivered quantity and the price based on the corresponding price list
models.execute_kw(db,uid, odoo_password, 'sale.order.line', 'write',
[[custom_sale_order_line_id],
{'qty_delivered': float(custom_product_qty),
'price_unit': float(custom_fixed_price),
}])
# create a new sale advance payment record in the odoo table "sale_advance_payment_inv"
custom_sale_advance_payment_inv = models.execute_kw(db,uid, odoo_password,'sale.advance.payment.inv', 'create',
[{
'advance_payment_method': 'delivered',
'amount': 0.0,
'count': 1,
'company_id': int(custom_company_id),
'create_uid': custom_create_uid,
'currency_id': int(custom_currency_id),
'deduct_down_payments': True,
'deposit_account_id': False,
'fixed_amount': 0.0,
'has_down_payments': False,
'write_uid': custom_create_uid,
'sale_order_ids': [(6,0,[custom_sale_order_id])],
}])
# create an invoice based on the sale order
# when creating an invoice, a journal entry in "account.move" is created
models.execute_kw(db, uid, odoo_password, 'sale.advance.payment.inv', 'create_invoices', [custom_sale_advance_payment_inv], {'context': {'active_ids': custom_sale_order_id}})
# togehter with the invoice record in "account.move", "account.move.line" records have been created
# find the newly created invoice line record with the correponding "sale_order_line_id" to get the "move_id" of the "sale.oder" record
account_move_line = models.execute_kw(db, uid, odoo_password, 'account.move.line', 'search_read',
[[['sale_line_ids', '=', custom_sale_order_line_id]]],
{'fields': [ 'move_id']})
# get the move_id of the invoice record
for key, value in list(account_move_line[0].items()):
if key == "move_id":
custom_account_move_id = value[0]
# update the invoice to the state "Posted"
models.execute_kw(db, uid, odoo_password, 'account.move', 'action_post', [custom_account_move_id])
result = (custom_sale_order_id, custom_sale_order_line_id)
else:
result = ('', '')
return(result)