From 137eb17d4f18def16309c69187e69d9869c5459e Mon Sep 17 00:00:00 2001 From: Alaguraj0361 Date: Sat, 28 Mar 2026 18:46:53 +0530 Subject: [PATCH] first commit - Week 1: C2C Odoo ERP base setup with multi-company, UoM engine, and core modules --- .gitignore | 20 +++++ addons/c2c_core/__init__.py | 2 + addons/c2c_core/__manifest__.py | 24 ++++++ addons/c2c_core/data/partner_data.xml | 19 +++++ .../c2c_core/data/product_category_data.xml | 17 ++++ addons/c2c_core/data/stock_location_data.xml | 20 +++++ addons/c2c_core/models/__init__.py | 2 + addons/c2c_core/models/product_template.py | 25 ++++++ .../c2c_core/views/product_template_views.xml | 14 ++++ addons/c2c_core/views/res_partner_views.xml | 13 +++ addons/c2c_uom_engine/__init__.py | 2 + addons/c2c_uom_engine/__manifest__.py | 21 +++++ addons/c2c_uom_engine/data/uom_data.xml | 25 ++++++ addons/c2c_uom_engine/models/__init__.py | 2 + .../models/uom_conversion_rule.py | 32 +++++++ .../security/ir.model.access.csv | 2 + .../views/uom_conversion_rule_views.xml | 34 ++++++++ docker-compose.yml | 33 ++++++++ weekone.md | 84 +++++++++++++++++++ 19 files changed, 391 insertions(+) create mode 100644 .gitignore create mode 100644 addons/c2c_core/__init__.py create mode 100644 addons/c2c_core/__manifest__.py create mode 100644 addons/c2c_core/data/partner_data.xml create mode 100644 addons/c2c_core/data/product_category_data.xml create mode 100644 addons/c2c_core/data/stock_location_data.xml create mode 100644 addons/c2c_core/models/__init__.py create mode 100644 addons/c2c_core/models/product_template.py create mode 100644 addons/c2c_core/views/product_template_views.xml create mode 100644 addons/c2c_core/views/res_partner_views.xml create mode 100644 addons/c2c_uom_engine/__init__.py create mode 100644 addons/c2c_uom_engine/__manifest__.py create mode 100644 addons/c2c_uom_engine/data/uom_data.xml create mode 100644 addons/c2c_uom_engine/models/__init__.py create mode 100644 addons/c2c_uom_engine/models/uom_conversion_rule.py create mode 100644 addons/c2c_uom_engine/security/ir.model.access.csv create mode 100644 addons/c2c_uom_engine/views/uom_conversion_rule_views.xml create mode 100644 docker-compose.yml create mode 100644 weekone.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dfac0a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Docker volumes - don't commit database data +.data/ +*.log + +# Python +__pycache__/ +*.pyc +*.pyo + +# Odoo compiled assets +/addons/**/static/lib/ +/addons/**/*.pyc + +# Temp scripts +check_removal.py +verify_week1.py +verify.log +uom_bad.log +verify_error.log +config_odoo.py diff --git a/addons/c2c_core/__init__.py b/addons/c2c_core/__init__.py new file mode 100644 index 0000000..a0fdc10 --- /dev/null +++ b/addons/c2c_core/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/addons/c2c_core/__manifest__.py b/addons/c2c_core/__manifest__.py new file mode 100644 index 0000000..f1dee48 --- /dev/null +++ b/addons/c2c_core/__manifest__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'C2C Core', + 'version': '1.0', + 'category': 'Base', + 'summary': 'Core configuration for C2C Agricorp implementation', + 'description': """ + - Configures product and partner categories. + - Adds fields for shelf life, expiry, and quality grades. + - Enables tracking and removal strategies. + """, + 'author': 'Antigravity', + 'depends': ['stock', 'purchase', 'sale_management', 'mrp', 'product_expiry'], + 'data': [ + 'data/partner_data.xml', + 'data/product_category_data.xml', + 'data/stock_location_data.xml', + 'views/product_template_views.xml', + 'views/res_partner_views.xml', + ], + 'installable': True, + 'application': True, + 'license': 'LGPL-3', +} diff --git a/addons/c2c_core/data/partner_data.xml b/addons/c2c_core/data/partner_data.xml new file mode 100644 index 0000000..faa4df0 --- /dev/null +++ b/addons/c2c_core/data/partner_data.xml @@ -0,0 +1,19 @@ + + + + + Farmers + + + Wholesalers + + + Retail Customers + + + Logistics Providers + + + Intercompany Partners + + diff --git a/addons/c2c_core/data/product_category_data.xml b/addons/c2c_core/data/product_category_data.xml new file mode 100644 index 0000000..a14f97f --- /dev/null +++ b/addons/c2c_core/data/product_category_data.xml @@ -0,0 +1,17 @@ + + + + Raw Materials + + + + + Semi-finished Goods + + + + + Finished Goods + + + diff --git a/addons/c2c_core/data/stock_location_data.xml b/addons/c2c_core/data/stock_location_data.xml new file mode 100644 index 0000000..35f572e --- /dev/null +++ b/addons/c2c_core/data/stock_location_data.xml @@ -0,0 +1,20 @@ + + + + + QC Hold + + internal + + + + Rejected/Scrap + + inventory + True + + diff --git a/addons/c2c_core/models/__init__.py b/addons/c2c_core/models/__init__.py new file mode 100644 index 0000000..2757b3a --- /dev/null +++ b/addons/c2c_core/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import product_template diff --git a/addons/c2c_core/models/product_template.py b/addons/c2c_core/models/product_template.py new file mode 100644 index 0000000..225fd1e --- /dev/null +++ b/addons/c2c_core/models/product_template.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + quality_grade = fields.Selection([ + ('a', 'Grade A'), + ('b', 'Grade B'), + ('c', 'Grade C'), + ], string='Quality Grade', default='a') + + # Many expiry fields are in product.template if product_expiry is installed + # shelf life (expiration time in days), etc. + +class ResPartner(models.Model): + _inherit = 'res.partner' + + partner_category_type = fields.Selection([ + ('farmer', 'Farmer'), + ('wholesaler', 'Wholesaler'), + ('retail_customer', 'Retail Customer'), + ('logistics', 'Logistics'), + ('intercompany', 'Intercompany'), + ], string='C2C Partner Category') diff --git a/addons/c2c_core/views/product_template_views.xml b/addons/c2c_core/views/product_template_views.xml new file mode 100644 index 0000000..8549af5 --- /dev/null +++ b/addons/c2c_core/views/product_template_views.xml @@ -0,0 +1,14 @@ + + + + product.template.form.inherit.c2c + product.template + + + + + + + + + diff --git a/addons/c2c_core/views/res_partner_views.xml b/addons/c2c_core/views/res_partner_views.xml new file mode 100644 index 0000000..6943bcd --- /dev/null +++ b/addons/c2c_core/views/res_partner_views.xml @@ -0,0 +1,13 @@ + + + + res.partner.form.inherit.c2c + res.partner + + + + + + + + diff --git a/addons/c2c_uom_engine/__init__.py b/addons/c2c_uom_engine/__init__.py new file mode 100644 index 0000000..a0fdc10 --- /dev/null +++ b/addons/c2c_uom_engine/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/addons/c2c_uom_engine/__manifest__.py b/addons/c2c_uom_engine/__manifest__.py new file mode 100644 index 0000000..3342439 --- /dev/null +++ b/addons/c2c_uom_engine/__manifest__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'C2C UoM Engine', + 'version': '1.0', + 'category': 'Inventory/Inventory', + 'summary': 'Multi-stage UoM conversion framework for Clickstocart', + 'description': """ + Stores conversion rules per product category/category. + Provides a server-side conversion utility for complex UoM constraints. + """, + 'author': 'Antigravity', + 'depends': ['stock'], + 'data': [ + 'security/ir.model.access.csv', + 'data/uom_data.xml', + 'views/uom_conversion_rule_views.xml', + ], + 'installable': True, + 'application': False, + 'license': 'LGPL-3', +} diff --git a/addons/c2c_uom_engine/data/uom_data.xml b/addons/c2c_uom_engine/data/uom_data.xml new file mode 100644 index 0000000..1154809 --- /dev/null +++ b/addons/c2c_uom_engine/data/uom_data.xml @@ -0,0 +1,25 @@ + + + + + + 500g + + smaller + 2.0 + + + + 100g + + smaller + 10.0 + + + + Bundle (3m) + + bigger + 3.0 + + diff --git a/addons/c2c_uom_engine/models/__init__.py b/addons/c2c_uom_engine/models/__init__.py new file mode 100644 index 0000000..106cf96 --- /dev/null +++ b/addons/c2c_uom_engine/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import uom_conversion_rule diff --git a/addons/c2c_uom_engine/models/uom_conversion_rule.py b/addons/c2c_uom_engine/models/uom_conversion_rule.py new file mode 100644 index 0000000..f8f263d --- /dev/null +++ b/addons/c2c_uom_engine/models/uom_conversion_rule.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api, _ +from odoo.exceptions import UserError + +class UoMConversionRule(models.Model): + _name = 'c2c.uom.conversion.rule' + _description = 'C2C UoM Conversion Rule' + + name = fields.Char(string='Rule Name', required=True) + product_category_id = fields.Many2one('product.category', string='Product Category') + from_uom_id = fields.Many2one('uom.uom', string='From UoM', required=True) + to_uom_id = fields.Many2one('uom.uom', string='To UoM', required=True) + ratio = fields.Float(string='Conversion Ratio', default=1.0, required=True, digits=(16, 4)) + description = fields.Text(string='Description') + + @api.model + def convert(self, product, quantity, from_uom, to_uom): + """ + Utility method to convert quantities based on local rules if they exist. + Otherwise falls back to standard Odoo UoM conversion. + """ + rule = self.search([ + ('product_category_id', '=', product.categ_id.id), + ('from_uom_id', '=', from_uom.id), + ('to_uom_id', '=', to_uom.id) + ], limit=1) + + if rule: + return quantity * rule.ratio + + # Fallback to Odoo standard + return from_uom._compute_quantity(quantity, to_uom) diff --git a/addons/c2c_uom_engine/security/ir.model.access.csv b/addons/c2c_uom_engine/security/ir.model.access.csv new file mode 100644 index 0000000..0cbe3c4 --- /dev/null +++ b/addons/c2c_uom_engine/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_c2c_uom_conversion_rule,c2c.uom.conversion.rule,model_c2c_uom_conversion_rule,base.group_user,1,1,1,1 diff --git a/addons/c2c_uom_engine/views/uom_conversion_rule_views.xml b/addons/c2c_uom_engine/views/uom_conversion_rule_views.xml new file mode 100644 index 0000000..b9a2b3b --- /dev/null +++ b/addons/c2c_uom_engine/views/uom_conversion_rule_views.xml @@ -0,0 +1,34 @@ + + + + c2c.uom.conversion.rule.tree + c2c.uom.conversion.rule + + + + + + + + + + + + + + Conversion Rules + c2c.uom.conversion.rule + list,form + + + + + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a4431f1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,33 @@ +version: "3.8" + +services: + db: + image: postgres:15 + container_name: odoo_clickstocart_db + environment: + POSTGRES_DB: postgres + POSTGRES_USER: odoo + POSTGRES_PASSWORD: odoo + volumes: + - client1_pgdata:/var/lib/postgresql/data + restart: always + + odoo: + image: odoo:17.0 + container_name: odoo_clickstocart + depends_on: + - db + ports: + - "10005:8069" + environment: + HOST: db + USER: odoo + PASSWORD: odoo + volumes: + - client1_odoo_data:/var/lib/odoo + - ./addons:/mnt/extra-addons + restart: always + +volumes: + client1_pgdata: + client1_odoo_data: \ No newline at end of file diff --git a/weekone.md b/weekone.md new file mode 100644 index 0000000..43ba3f2 --- /dev/null +++ b/weekone.md @@ -0,0 +1,84 @@ +# Week 1 Implementation Guide & Verification Manual + +This document is your complete step-by-step guide on how to manually verify and test all the Week 1 features directly within the Odoo user interface. + +--- + +## 1. How to Check: Multi-Company Architecture +**Goal**: Verify that all 3 companies and their isolated warehouses exist. + +**Instructions**: +1. Login to `NewClickstoCart` as the administrator. +2. Look at the top-right corner of the top navigation bar. Click on the **Company Switcher** (the building icon next to your profile picture). +3. **Verify:** You should see checkboxes for `C2C Agricorp India Pvt Ltd`, `C2C Imports & Exports`, and `Clickstocart Inc`. +4. Click on the **Settings app** > **Users & Companies** > **Companies**. +5. **Verify:** The 3 companies are listed here with their respective details. +6. Still in Settings, navigate to **Users & Companies** > **Groups**. +7. **Verify:** Search for "Manufacturing Manager", "Warehouse Staff", etc. You will see these roles exist for assigning to future employees. +8. Open the **Inventory app** > **Configuration** > **Warehouses**. +9. **Verify:** You should see one distinct warehouse per company (e.g., `C2C - C2C Agricorp`, `C2C - Clickstocart`). + +--- + +## 2. How to Check: Master Data Fields (Products & Partners) +**Goal**: Verify custom fields and categorized data templates. + +**Instructions (Partners/Contacts)**: +1. Open the **Contacts app**. +2. Click **New** to create a test contact. +3. In the form, look closely below the tags/categories area or in the main tabs. +4. **Verify:** You will see a new dropdown field called **C2C Partner Category**. Click it to ensure options like `Farmer`, `Wholesaler`, `Retail Customer` exist. + +**Instructions (Products)**: +1. Open the **Inventory app** > **Products** > **Products**. +2. Click **New**. +3. Under the **General Information** page, click the **Product Category** dropdown. +4. **Verify:** You will see categories explicitly created for us: `Raw Materials`, `Semi-finished Goods`, and `Finished Goods`. +5. Still on the product form, look at the bottom of the main fields. +6. **Verify:** There is a new dropdown called **Quality Grade** containing `Grade A`, `Grade B`, `Grade C`. +7. Go to the **Inventory tab** on the product form. +8. **Verify:** Under **Traceability**, ensure the **By Lots** option is available. Check the **Expiration Date** box to see the `Shelf Life` fields appear. + +--- + +## 3. How to Check: UoM Engine +**Goal**: Test the new complex conversion engine and the new standard units. + +**Instructions**: +1. Open the **Inventory app**. +2. Navigate to **Configuration** > **Units of Measure** (Check 'UoM Categories' if 'Units of Measure' isn't directly visible). +3. **Verify:** Search for `500g`, `100g`, or `Bundle (3m)`. They are fully registered in the standard weight/length systems. +4. Navigate to **Configuration** > **Conversion Rules** (Under the new "UoM Engine" section). +5. **Verify:** This is the new custom dashboard. Click **New**. You can now define a rule that says "For Category X, converting from Y to Z uses Ratio R". + +--- + +## 4. How to Check: Batch/Expiry & QC Workflow +**Goal**: Verify that Odoo enforces FEFO (First Expired First Out) and has a location to hold quality checks. + +**Instructions (QC Locations)**: +1. In the **Inventory app**, turn on Developer Mode if you can't see the Locations menu. +2. Go to **Configuration** > **Locations**. +3. **Verify:** Remove the "Internal" filter in the search bar and search for `QC Hold`. You will see it exists as an Internal Location. +4. **Verify:** Search for `Rejected/Scrap`. It exists and has the flag "Is a Scrap Location" checked. + +**Instructions (FEFO Strategy)**: +1. Go to **Inventory app** > **Configuration** > **Product Categories**. +2. Open the `Raw Materials` category. +3. **Verify:** Scroll down to the Logistics section. The **Force Removal Strategy** is set to `First Expired, First Out (FEFO)`. + +--- + +## 5. End-to-End Test: The Farmer Procurement Flow +To see everything working together, perform this exact sequence: + +1. **Prep**: Create a Product named "Test Turmeric", set tracking to "By Lots", and check "Expiration Date" (give it 100 days shelf life). +2. **Purchase**: Open the **Purchase app**. Select a vendor/Farmer. Add "Test Turmeric" and click **Confirm Order**. +3. **Receipt**: Click the **Receive Products** button in the top right of the Purchase Order. +4. **Create Lot**: On the receipt line for Turmeric, you cannot validate yet. Click the **List icon (Options/Details)** on the right side of the product line. +5. Under "Assign Serial/Lot Number", type in `LOT-001` and set an Expiration Date for tomorrow. Apply and **Validate** the receipt. +6. **QC Transfer**: Open the **Inventory app** > **Operations** > **Transfers**. Create a new internal transfer. +7. Set the Source Location as `WH/Stock` (where the goods just arrived) and the Destination Location to `QC Hold`. +8. Add the Product, select `LOT-001`, and **Validate**. + +### **Congratulations!** You have just executed a full cycle of Procurement -> Quality Control with multi-stage Lot tracking and Expiry enforcement.