Odoo Demand Planning

I am writing this blog after a very long time.  Over the past few months, I was exploring the strengths of python language and realize it is just amazing when it comes to Machine Learning. The ultimate goal of ML algorithms is to be able to take decisions without any human intervention.

After implementing large scale multi-country multi-company Odoo projects, I realize it is time to take Odoo customization to next level and develop apps which helps business in making strategic decisions by projecting future sales. Here, is one such app developed by me- Demand Planning.

This app can be used to analyze your historical sales, project your future demands, and then create orders according to a supply plan that will add stock as needed. Demand Planning App works in 3 stages:-

  1. Demand Plan– This will calculate the expected future demand for a product based on historical demand. It is here where various time series forecasting models are being used.
  2. Supply Plan– This provides a list of purchase and manufacturing orders. It considers lead times so that orders are placed in time. Purchase orders generated uses the first vendor from the product master which can be changed later. For assembly products, all sub-components are considered and appropriate manufacturing or purchase orders are created for raw materials.
  3. Order Creation– This allows the actual creation of purchase and manufacturing orders from locked supply plans.

For more information, click here- https://lnkd.in/egRHCsk

 

Point of Sale with 2D Barcode in Odoo

In my previous blog, I published use of Weight and Price Barcode. In this blog, we will see how with slight customization of point of sale module we can make use of combination of weight and price barcode.

Let me first start with 2D barcode. In this type, we can merge multiple barcodes into one. Example of 2D barcodes are DataMatrix, PDF417, QRCode, Aztec, etc. Here, is a sample output when a 2D barcode is scanned- 3330012244123,3330013355123,3330014466123.

Barcodes can be separated either by comma or tab or newline character. Now, this structure can be utilized in Point of Sale for selling combo products. Consider an example. We are selling Boni Oranges and Golden Apples wrapped in a decorative tray. Now, the total price of the product includes weight of two fruits plus cost of the tray. Hence, we can combine 2 weight barcode and 1 price barcode into a 2D barcode.

For more information on Weight, Price and Discount Barcode please refer to my blog- Point of Sale with Weight, Price and Discount Barcode in Odoo

Let’s understand with an example-

Product 1-
Name: Boni Orange
Internal Reference: 929000
Weight: 400g
Weight Barcode: 21 929000 00400

Product 2-
Name: Golden Apples Perlim
Internal Reference: 929001
Weight: 600g
Weight Barcode: 21 929001 00600

Product 3-
Name: Decorative Item
Internal Reference: 666001
Price: 2500
Price Barcode: 23 666001 02500

We will now merge all 3 barcode and generate a 2D Barcode as follows:

PDF-417 Barcode
PDF-417 Barcode

OR

DataMatrix Barcode
DataMatrix Barcode

Now, when this barcode is scanned all 3 above product comes automatically.

Point of Sale
Point of Sale

This way the scan function of Point of Sale can be made smart enough to achieve various requirements.

Note- You need a 2D Barcode scanner to read such barcodes.

Point of Sale with Weight, Price and Discount Barcode in Odoo

In this blog, I will explain how with slight customization of point_of_sale module, we can make use of weight and price barcode. This is how I have configured the system.

POS Configuration
POS Configuration

Weight Barcode has prefix of ’21’ followed by 6 digits Internal Reference followed by 5 digits weight.

Product Configuration
Product Configuration

Then, when the product is weighed on weighing machine, we get a barcode as follows (Note- This barcode is generated through weighing machines)-

Weight Barcode
Weight Barcode

Now, when this is scan in Point of Scale, Odoo automatically pulls the right product with the right quantity.

Point of Sale
Point of Sale

Similarly, Price Barcode has ’23’ as prefix followed by 6 digits Internal Reference followed by 5 digit numeric price.

Consider you have a product called Decorative Item and its price changes based on customer’s request. So, we can keep one product and change its price in PoS using Price Barcode.

DecorativeItem

Now, we will generate a price barcode to enable PoS pick the right price as soon as it is scanned. (Note- This barcode is generated using barcode softwares)

Price Barcode
Price Barcode

When this barcode is scanned, Odoo picks the decorative item with the given price.

Point of Sale
Point of Sale

On similar principle, we can make use of Discount Barcode during promotions.

Manufacturing Subcontracting in Odoo/OpenERP

In a manufacturing process, we might have to outsource some or all of the operations. Here, two things are involved-

I. Stock Management

We have to make a stock move from Raw Material location to Contractor (Production) location. To do this, we set Production location on the relevant Routing document.

Production Location- Routing
Production Location- Routing

The production location should be configured with the following data:
Location Type: Supplier,
Location Address: Select an address of the subcontracting partner,
Chained Location Type: Fixed,
Chained Location if Fixed: your Stock,
Chaining Lead Time: number of days before receipt of the finished product.

However, if the Contractor location is different for each Work Center operation, then we have to customize it.

II. Accounting

In order to achieve this we first have to define Analytic Account. It has Customer field where we have to select the Partner to whom this process is going to be outsourced.

Analytic Account
Analytic Account

Next, in Work Center configuration we set the Hour Account (for discrete manufacturing) or Cycle Account (for continuous manufacturing).

Work Center
Work Center

Finally, when manufacturing process is completed system generates Analytic Entries which can be used for invoicing our sub-contractor. Using the “Invoiceable” field, we can either Invoice full 100% or do partial invoicing (90%,80% and so on).

Analytic Journal Item
Analytic Journal Item

Finally, using the More button we can Create Invoice. We can create Invoice for each Analytic item separately or merge multiple items belonging to same Contractor.

Create Invoice- Analytic Account
Create Invoice- Analytic Account

On clicking Create Invoice button, an Invoice gets created which can be validated and followed up for payment.

Here, we have to replace Customer Invoice with Supplier Invoice so that outsourcing cost is booked as expense and not income.

Manufacturing Accounting in Odoo/OpenERP

There are 2 types of accounting integration

i. Real-time Accounting Valuation
ii. Analytic Accounts

Real-time Accounting Valuation

Here, each stock movement generates a corresponding accounting entry in an accounting journal. You need to configure your Raw Material location and/or Production location and Finished Products Location in Routings.

Location Configuration in Routing
Location Configuration in Routing

Next, set up a general account for each location that should be valued in your accounts. If a product goes to one location or another and the accounts are different in the two locations, Odoo automatically generates the corresponding accounting entries in the accounts, in the stock journal.

Remember, in the Product form, go to the Accounting tab and select the Real Time(automated) option for Inventory Valuation. To define your accounts, you have two options. Set them on the product category, or on the product.

  1. From the Accounting Stock Properties section, for the Product Category, set the Stock Input Account, the Stock Output Account and the Stock Valuation Account

    Accounting Stock Properties
    Accounting Stock Properties- Product Category
  2. From the Accounting tab, for the Product, set the Stock Input Account and the Stock Output Account.

    Accounting Stock Properties- Product
    Accounting Stock Properties- Product

You can also overwrite the accounts from the Product or the Product Category by defining Stock Input Account and Stock Output Account for a Location.

Here, is a sample journal entry for stock move of a product from Raw Material location -> Semi Finished Location -> Virtual Location

Stock Move

Stock Move

This helps in valuating different location during a manufacturing operation.

Analytic Accounts

In manufacturing operation, there are 3 types of cost involved- Material, People and Machine. Whenever manufacturing order is created these analytic account gets created automatically. The feature listed here is not available in default installation.

AnalyticAccount
Analytic Account

i. Material Cost– This is achieved through Bill of Materials. An analytic entry is made whenever stock move happens from Stock to Virtual location.

Analytic Account- Material
Analytic Account- Material

ii. People Cost– This is achieved by linking manufacturing with HR time-sheets. This feature is not there in the default installation. Ideally, an analytic account should be created against each manufacturing order. And employees keep on adding line to time sheets with details of the time used on that manufacturing order.

Alternatively, this can also be achieved through Work Center of type Human. We can set an hourly rate for a particular operation. At the end, we put total number of hours consumed and accordingly system calculates the actual cost.

WorkCenter-Human
WorkCenter-Human

iii. Machine Cost

For this we have to configure Work Centers of type Material. If it is discrete manufacturing we configure Hour Account and if it is continuous manufacturing we configure Cycle Account. Also, we specify Cost per hour / Cost per cycle for each operation.

Work Center- Material
Work Center- Material

Finally, when the manufacturing order is completed system makes analytic entries for each work center operation for which analytic account is configured.

Analytic Journal Items
Analytic Journal Items

Chart of Analytic Accounts give us complete expense of Material, Human and Machine

Chart of Analytic Account
Chart of Analytic Account

Linking HR Organisation Structure to Approval Process in Odoo

There is no direct link between Organization Structure and access rights. In HR Configuration, we define employees of a company. Next, we create user accounts to give employees access to Odoo. We then link Employee to User in Employee form by using the menu Human Resources ‣ Employees.

Employee form
Employee form

Each user is then linked to groups which defines its access rights.

User Access Rights
User Access Rights

Now, we can control approval process using these groups.

For example, in order to allow only sales manager to approve quotations we can give-
<button name="quotation_approved" states="confirmed" type="object" string="Approve" class="oe_highlight" groups="base.group_sale_manager" />

Similarly, we can make fields, groups, page visible only to users of a particular groups by using ‘groups’ attribute
<field name="incoterm" widget="selection" groups="base.group_user"/>
<group name="sales_person" groups="base.group_user">
<page string="Other Information" groups="base.group_user">

So, this way groups can be used to limit access to directors, managers, users, etc. and approval process at various levels can be achieved.

Manufacturing Order and Costing in OpenERP/Odoo

The current manufacturing module of Odoo has certain missing features-

1. We don’t have configuration for multiple Raw Material Location
2. Issuing products to Production (Semi-finished) location is missing
3. Cannot select another BOM for Manufacturing Order created automatically from Sales Order
4. There is no track of Estimated and Actual Cost
5. No field to track total cost of production

In order to enable creation of Manufacturing Order from Sales Order and also automatic generation of Purchase Requisition for raw materials, the configuration steps is as follows. Also, to achieve the above listed advanced features customization have been done. Here are the steps

  1. Finished Product Configuration– The product is defined as “Stockable”. Costing method should be set to Standard (so that the accounting impact pulls the price from Manufacturing Order). Select routes as Make to Order and Manufacture.
  2.  Raw Material Product Configuration– The product should be set to “Stockable” if stock management is required else set to “Consumables”. Costing method should be set to Average (we are assuming here that raw materials will always be bought from Supplier). Select routes as Make to Order and Buy. Default Raw Material location of this product can also be configured under Inventory tab.

    Raw Material Location Configuration
    Raw Material Location Configuration
  3.  Bill of Material Configuration– Goto Manufacturing -> Products -> Bill of Materials in order to define BOM for every product.
  4. Routing Configuration– Next, we define different operations through which the raw materials will go through. We also specify default Raw Materials and Finished Products Location. Make sure right Semi Finished Location is also selected. Once routing is defined we attach it to BOM. Here, we have customized to allow users to add default Raw Material and Finished Product Location so that when Manufacturing Order gets created it pulls the location from here.

    Configuring Finished Product location
    Routing Configuration
  5. Estimating Cost– A new button is provided in Sales Quotation. Based on this estimated cost salesman adds profit margin to get the final sale price of the order.
    Estimating Cost
    Manufacturing Cost Estimation

    On clicking, system automatically pulls 2 things-

      • Raw Materials defined in BOM and
      • Operations defined in Routing

    The subtotal and quantity comes from these configurations. User can click on green button to change the quantity (no. of hours) of an operation. The subtotal and total estimated cost gets adjusted accordingly.

    Estimated Cost
    Estimated Cost
  6. Fetching Estimated Cost in Quotation Line– A button is provided in quotation line as shown below
    Fetching Estimated Cost
    Fetching Estimated Cost

    When the button is clicked then it asks for Profit Margin and accordingly updates the unit price of the quotation line

    Add profit margin to estimated cost
    Add profit margin to estimated cost

    The price has been updated-

    Updating Estimated Price
    Updating Estimated Price
  7. Manufacturing Order– Finally, when the quotation is converted to order then automatically manufacturing order gets created.At this stage, Delivery Order shows Waiting Another Operation as MO needs to be completed
    Delivery Order Waiting Another Operation
    Delivery Order Waiting Another Operation

    MO created is in draft state so that user can verify all the details before confirming it. Also, a product can have multiple BOM so make sure right one is selected.

    Manufacturing Order in draft state
    Manufacturing Order in draft state

    (a) Buying of Raw Material

    After MO is confirmed, then click on Check Availability to automatically raise Purchase Requisition against the supplier configured in Product Master. If the raw material is already there in stock then click on Force Reservation button as shown in the following diagram

    Buying Raw Material
    Buying Raw Material

    Purchase Requisition gets created. The system smartly merges all products into one which is being bought from one supplier and coming into same Raw Material location. The full workflow is followed and we receive all raw materials.

    (b) Issuing Raw Materials to Work in Process locations

    Before we purchase raw materials, the Issue Products tab shows products in red. But once the product is purchased and available in stock then the color changes to black. Here, the stock move created pulls source location from the Raw Material Location field configured in Product Master. This way each material can have different source location.

    (b)Issuing Raw Materials to Work in Process locations
    Issue Raw Materials to Work in Process locations

    We then click on green button to issue them to Work in Process location

    Raw Materials Issued to Work in Process location
    Raw Materials Issued to Work in Process location

    (c) Start Production

    Click on Mark as Started button on the header to start production. This will generate costing of BOM in cost breakdown tab.

    Start Production
    Start Production

    Cost Breakdown tab lists actual raw material costing

    Actual Cost Breakdown
    Actual Cost Breakdown

    (d) Process Work Orders

    Work Orders tab lists all the operations defined in Routing. Number of Hours field is editable so that user can enter the actual no. of hours spent on each operation. As each work order is completed, Cost Breakdown tab lists the actual costing.

    Actual Cost Breakdown showing Work Center Operations
    Actual Cost Breakdown

    (e) Finally when all the work orders are completed then we hit Finish Production. Total cost field shows the actual costing of the product

    Finish Production
    Finish Production

    The MO state now shows Done. The delivery order state also changes to Ready to Transfer

    Delivery order changes to Ready to Transfer
    Delivery order changes to Ready to Transfer
  8. Delivery Order–  Finally we transfer the finished product to our customer by clicking on Transfer button.

Creating Dynamic Many2One field with onchange function in OpenERP


This post will help in creating many2one field whose value changes when the content of another field changes.

Lets consider a simple example. Suppose we have a many2one field to Product (name: product_id). We now want to change the content on this many2one field based on type selection box(name: type). Now, if I choose type as Service, only service type product should be visible in Product field.

To accomplish this, we have to define on change function on type selection box.

def onchange_type(self,cr,uid,ids, type,context=None):
    product_obj = self.pool.get('product.product')
    product_ids = product_obj.search(cr,uid, [('type','=',type)])
    return {'domain':{'product_id':[('id','in',product_ids)]}}

Ebay workflow for Ending a listing early

Ending a multi-variation listing is quite complicated. Many parameters needs to be checked before calling EndItem API. Flowchart below helps in understanding the flow involved-

Image

– How do I know if an Item is a variation one?

If GetItem API returns <Variations> tag, then it is a multi-variant listing

– How do I get quantity of a variation listing?

Inside <Variation> tag, there are <Quantity> and <QuantitySold> tags. Subtract the two to get available quantity

Reports in OpenERP using Views

Here, by reports I mean to combine more than one table to give user some useful information.

One way of doing it is to put related field in an object to replicate other object’s data. For eg., if I want to show sale.order Reference No. and Order Date fields in sale.order.line object, then I can make 2 related fields in sale.order.line to capture the data. But this will unnecessarily increase your DB size. So, a better option is to use views.

Views is same as what we define at database level.  Apart from providing summary information, views can be used to show data of 2 or more tables in one screen. Now, lets see how we can do this in OpenERP-

Step 1- Creating a class

Create a class with _auto=False. This ensures PostgreSQL table is not generated.

Step 2- Defining columns

Column names should be same as what we will define in views.

Step 3- Providing View definition

In def init(), we need to provide view definition such that the select clause has field names which exactly matches the name defined in _columns.

For sample, check addons/sale/report/sale_report.py.