@ -0,0 +1,51 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-OPL--1-red.svg |
||||
|
:target: https://www.odoo.com/documentation/17.0/legal/licenses.html#odoo-apps |
||||
|
:alt: License: OPL-1 |
||||
|
|
||||
|
Courier Management |
||||
|
================== |
||||
|
This module helps you to create and manage courier requests for the courier management. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
No additional configuration required |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
Odoo Proprietary License v1.0 (OPL-1) |
||||
|
(https://www.odoo.com/documentation/17.0/legal/licenses.html#odoo-apps) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
Developer: (V15) Gayathri V, |
||||
|
(V16) Albin PJ |
||||
|
(V17) Saneen K, |
||||
|
(V18) Safa Faheem PE |
||||
|
Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
----------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import controllers |
||||
|
from . import models |
@ -0,0 +1,83 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
{ |
||||
|
'name': 'Courier Management', |
||||
|
'version': '18.0.1.0.0', |
||||
|
'category': 'Extra Tools', |
||||
|
'summary': """This module allows you to create and manage courier |
||||
|
requests""", |
||||
|
'description': 'This module helps you to create and manage courier ' |
||||
|
'requests for the courier management.Courier Management ' |
||||
|
'module is designed to efficiently manage and track the ' |
||||
|
'movement of goods or packages within your organization.' |
||||
|
' This module streamlines the delivery processes,ensuring' |
||||
|
' that your shipments are handled smoothly and delivered ' |
||||
|
'to the right recipients in a timely manner.', |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'maintainer': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['contacts', 'mail', 'stock', 'account', 'website'], |
||||
|
'data': [ |
||||
|
'security/courier_management_groups.xml', |
||||
|
'security/courier_request_security.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
'views/account_move_views.xml', |
||||
|
'views/courier_request_views.xml', |
||||
|
'views/courier_detail_views.xml', |
||||
|
'views/courier_tag_views.xml', |
||||
|
'views/courier_priority_views.xml', |
||||
|
'views/courier_dimension_price_views.xml', |
||||
|
'views/courier_distance_price_views.xml', |
||||
|
'views/courier_weight_price_views.xml', |
||||
|
'views/courier_type_views.xml', |
||||
|
'views/courier_category_views.xml', |
||||
|
'views/courier_management_menus.xml', |
||||
|
'views/courier_request_templates.xml', |
||||
|
'views/courier_request_search_group_by_templates.xml', |
||||
|
'data/courier_request_data.xml', |
||||
|
'report/courier_request_reports.xml', |
||||
|
'report/courier_request_templates.xml' |
||||
|
], |
||||
|
'demo': [ |
||||
|
'data/product_product_demo.xml', |
||||
|
'data/courier_categories_demo.xml', |
||||
|
'data/courier_priority_demo.xml', |
||||
|
'data/courier_weight_price_demo.xml', |
||||
|
'data/courier_dimension_price_demo.xml', |
||||
|
'data/courier_distance_price_demo.xml', |
||||
|
'data/courier_tag_demo.xml', |
||||
|
'data/courier_type_demo.xml', |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_frontend': [ |
||||
|
'courier_management/static/src/js/courier_request_group_by_search.js', |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'OPL-1', |
||||
|
'price': 29, |
||||
|
'currency': 'EUR', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': True, |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import courier_management |
@ -0,0 +1,125 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import http |
||||
|
from odoo.http import request |
||||
|
from odoo.addons.portal.controllers import portal |
||||
|
|
||||
|
|
||||
|
class CourierRequests(http.Controller): |
||||
|
"""This controller is for portal""" |
||||
|
|
||||
|
def _get_courier_domain(self): |
||||
|
"""It returns the login person""" |
||||
|
return [('sender_id', '=', request.env.user.partner_id.id)] |
||||
|
|
||||
|
@http.route(['/my/courier/requests'], type='http', auth="user", |
||||
|
website=True) |
||||
|
def get_my_courier_requests(self): |
||||
|
"""Take values from courier requests and render to portal tree |
||||
|
template """ |
||||
|
domain = self._get_courier_domain() |
||||
|
values = { |
||||
|
'courier_request': request.env['courier.request'].sudo().search( |
||||
|
domain), |
||||
|
} |
||||
|
return request.render( |
||||
|
"courier_management.portal_my_courier_requests_tree", values) |
||||
|
|
||||
|
@http.route(['/my/courier/requests/form/<int:courier_id>'], type='http', |
||||
|
auth="user", website=True) |
||||
|
def get_my_courier_request_form(self, courier_id): |
||||
|
"""Take values from courier_request and render to portal form |
||||
|
template.It also passes the id in the root for rendering the |
||||
|
corresponding form template""" |
||||
|
return request.render( |
||||
|
"courier_management.portal_my_courier_requests_form", |
||||
|
{'record_courier_requests': request.env[ |
||||
|
'courier.request'].sudo().browse(courier_id)}) |
||||
|
|
||||
|
@http.route(['/courier/requests/group/by'], type='json', auth="public", |
||||
|
website=True) |
||||
|
def courier_requests_group_by(self, **kwargs): |
||||
|
"""Call from rpc for group by, and it returns the corresponding |
||||
|
values""" |
||||
|
context = [] |
||||
|
group_value = kwargs.get("search_value") |
||||
|
if group_value == '1': |
||||
|
context = [] |
||||
|
for types in request.env['courier.type'].sudo().search([]): |
||||
|
courier_requests_ids = request.env[ |
||||
|
'courier.request'].sudo().search([ |
||||
|
('type_id', '=', types.id), |
||||
|
('sender_id', '=', request.env.user.partner_id.id) |
||||
|
]) |
||||
|
if courier_requests_ids: |
||||
|
context.append({ |
||||
|
'name': types.courier_type, |
||||
|
'data': courier_requests_ids |
||||
|
}) |
||||
|
if group_value == '2': |
||||
|
context = [] |
||||
|
for categories in request.env['courier.category'].sudo().search( |
||||
|
[]): |
||||
|
courier_requests_ids = request.env[ |
||||
|
'courier.request'].sudo().search([ |
||||
|
('category_id', '=', categories.id), |
||||
|
('sender_id', '=', request.env.user.partner_id.id) |
||||
|
]) |
||||
|
if courier_requests_ids: |
||||
|
context.append({ |
||||
|
'name': categories.courier_category, |
||||
|
'data': courier_requests_ids |
||||
|
}) |
||||
|
values = { |
||||
|
'courier_request': context, |
||||
|
} |
||||
|
response = http.Response( |
||||
|
template='courier_management.courier_requests_group_by_template', |
||||
|
qcontext=values) |
||||
|
return response.render() |
||||
|
|
||||
|
@http.route(['/courier/requests/search'], type='json', auth="public", |
||||
|
website=True) |
||||
|
def courier_requests_search(self, **kwargs): |
||||
|
"""It gives the values and return the response to corresponding |
||||
|
template""" |
||||
|
record = request.env["courier.request"].sudo().search( |
||||
|
[('name', 'ilike', f'{kwargs.get("search_value").upper()}%'), |
||||
|
('sender_id', '=', request.env.user.partner_id.id)]) |
||||
|
response = http.Response( |
||||
|
template='courier_management.portal_my_certificates_search', |
||||
|
qcontext={'courier_request': record}) |
||||
|
return response.render() |
||||
|
|
||||
|
|
||||
|
class Return(portal.CustomerPortal): |
||||
|
"""This will take the count of total courier requests""" |
||||
|
|
||||
|
def _prepare_home_portal_values(self, counters): |
||||
|
"""This will return the certificates count""" |
||||
|
values = super(Return, self)._prepare_home_portal_values(counters) |
||||
|
values.update({ |
||||
|
'courier_requests_count': request.env[ |
||||
|
'courier.request'].sudo().search_count( |
||||
|
[('sender_id', '=', request.env.user.partner_id.id)]) |
||||
|
}) |
||||
|
return values |
@ -0,0 +1,27 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier category demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_categories_wooden_products" model="courier.category"> |
||||
|
<field name="courier_category">Wooden Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_metal_products" model="courier.category"> |
||||
|
<field name="courier_category">Metals Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_ceramic_products" model="courier.category"> |
||||
|
<field name="courier_category">Ceramic Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_glass_products" model="courier.category"> |
||||
|
<field name="courier_category">Glass Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_plastic_products" model="courier.category"> |
||||
|
<field name="courier_category">Plastic Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_solid_products" model="courier.category"> |
||||
|
<field name="courier_category">Solid Products</field> |
||||
|
</record> |
||||
|
<record id="courier_categories_other_products" model="courier.category"> |
||||
|
<field name="courier_category">Other Products</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,78 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier dimension price demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_dimension_price_rule_33_18_10" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">33 X 18 X 10</field> |
||||
|
<field name="length">33</field> |
||||
|
<field name="width">18</field> |
||||
|
<field name="height">10</field> |
||||
|
<field name="price">15</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_33_32_10" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">33 X 32 X 10</field> |
||||
|
<field name="length">33</field> |
||||
|
<field name="width">32</field> |
||||
|
<field name="height">10</field> |
||||
|
<field name="price">15</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_33_33_19" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">33 X 33 X 19</field> |
||||
|
<field name="length">33</field> |
||||
|
<field name="width">33</field> |
||||
|
<field name="height">19</field> |
||||
|
<field name="price">15</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_33_33_35" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">33 X 33 X 35</field> |
||||
|
<field name="length">33</field> |
||||
|
<field name="width">33</field> |
||||
|
<field name="height">35</field> |
||||
|
<field name="price">25</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_42_37_36" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">42 X 37 X 36</field> |
||||
|
<field name="length">42</field> |
||||
|
<field name="width">37</field> |
||||
|
<field name="height">36</field> |
||||
|
<field name="price">35</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_49_41_39" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">49 X 41 X 39</field> |
||||
|
<field name="length">49</field> |
||||
|
<field name="width">41</field> |
||||
|
<field name="height">39</field> |
||||
|
<field name="price">50</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_54_44_42" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">54 X 44 X 42</field> |
||||
|
<field name="length">54</field> |
||||
|
<field name="width">44</field> |
||||
|
<field name="height">42</field> |
||||
|
<field name="price">55</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_50_50_50" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">50 X 50 X 50</field> |
||||
|
<field name="length">50</field> |
||||
|
<field name="width">50</field> |
||||
|
<field name="height">50</field> |
||||
|
<field name="price">60</field> |
||||
|
</record> |
||||
|
<record id="courier_dimension_price_rule_40_40_40" |
||||
|
model="courier.dimension.price"> |
||||
|
<field name="name">40 X 40 X 40</field> |
||||
|
<field name="length">40</field> |
||||
|
<field name="width">40</field> |
||||
|
<field name="height">40</field> |
||||
|
<field name="price">47</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,62 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier distance price demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_distance_price_rule_5_to_15" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 5.00 To 15.00 Kilometres</field> |
||||
|
<field name="minimum_distance">5.00</field> |
||||
|
<field name="maximum_distance">15.00</field> |
||||
|
<field name="price">20</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_15_to_30" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 15.00 To 30.00 Kilometres</field> |
||||
|
<field name="minimum_distance">15.00</field> |
||||
|
<field name="maximum_distance">30.00</field> |
||||
|
<field name="price">35</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_30_to_50" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 30.00 To 50.00 Kilometres</field> |
||||
|
<field name="minimum_distance">30.00</field> |
||||
|
<field name="maximum_distance">50.00</field> |
||||
|
<field name="price">45</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_50_to_80" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 50.00 To 80.00 Kilometres</field> |
||||
|
<field name="minimum_distance">50.00</field> |
||||
|
<field name="maximum_distance">80.00</field> |
||||
|
<field name="price">60</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_80_to_100" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 80.00 To 100.00 Kilometres</field> |
||||
|
<field name="minimum_distance">80.00</field> |
||||
|
<field name="maximum_distance">100.00</field> |
||||
|
<field name="price">75</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_100_to_130" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 100.00 To 130.00 Kilometres</field> |
||||
|
<field name="minimum_distance">100.00</field> |
||||
|
<field name="maximum_distance">130.00</field> |
||||
|
<field name="price">90</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_130_to_150" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 130.00 To 150.00 Kilometres</field> |
||||
|
<field name="minimum_distance">130.00</field> |
||||
|
<field name="maximum_distance">150.00</field> |
||||
|
<field name="price">100</field> |
||||
|
</record> |
||||
|
<record id="courier_distance_price_rule_150_to_200" |
||||
|
model="courier.distance.price"> |
||||
|
<field name="name">If Distance 150.00 To 200.00 Kilometres</field> |
||||
|
<field name="minimum_distance">150.00</field> |
||||
|
<field name="maximum_distance">200.00</field> |
||||
|
<field name="price">150</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,34 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier priority demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_priority_standard_delivery_service" model="courier.priority"> |
||||
|
<field name="name">Standard Delivery Service</field> |
||||
|
<field name="charges">10</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_same_day_delivery" model="courier.priority"> |
||||
|
<field name="name">Same Day Delivery</field> |
||||
|
<field name="charges">20</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_overnight_shipping_service" model="courier.priority"> |
||||
|
<field name="name">Overnight Shipping Service</field> |
||||
|
<field name="charges">15</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_rush_and_on_demand_deliveries" model="courier.priority"> |
||||
|
<field name="name">Rush And On-Demand Deliveries</field> |
||||
|
<field name="charges">25</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_parsel_service" model="courier.priority"> |
||||
|
<field name="name">Parsel Service</field> |
||||
|
<field name="charges">20</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_luggage_delivery_service" model="courier.priority"> |
||||
|
<field name="name">Luggage Delivery Service</field> |
||||
|
<field name="charges">18</field> |
||||
|
</record> |
||||
|
<record id="courier_priority_expensed_service" model="courier.priority"> |
||||
|
<field name="name">Expensed Service</field> |
||||
|
<field name="charges">100</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Sequence number for courier requests--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="sequence_courier_requests" model="ir.sequence"> |
||||
|
<field name="name">Courier Requests</field> |
||||
|
<field name="code">courier.request</field> |
||||
|
<field name="active">TRUE</field> |
||||
|
<field name="prefix">COURIER/</field> |
||||
|
<field name="padding">5</field> |
||||
|
<field name="number_next">1</field> |
||||
|
<field name="number_increment">1</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,39 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier tags demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_tags_service" model="courier.tag"> |
||||
|
<field name="courier_tags">Courier Service</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_logistics" model="courier.tag"> |
||||
|
<field name="courier_tags">Logistics</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_expensed" model="courier.tag"> |
||||
|
<field name="courier_tags">Expensed</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_important" model="courier.tag"> |
||||
|
<field name="courier_tags">Important</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_shipping" model="courier.tag"> |
||||
|
<field name="courier_tags">Shipping</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_weightless" model="courier.tag"> |
||||
|
<field name="courier_tags">Weightless</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_electrical" model="courier.tag"> |
||||
|
<field name="courier_tags">Electrical</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_handle_with_care" model="courier.tag"> |
||||
|
<field name="courier_tags">Handle With Care</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_cargo" model="courier.tag"> |
||||
|
<field name="courier_tags">Cargo</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_inventory" model="courier.tag"> |
||||
|
<field name="courier_tags">Inventory</field> |
||||
|
</record> |
||||
|
<record id="courier_tags_cross_docking" model="courier.tag"> |
||||
|
<field name="courier_tags">Cross Docking</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,24 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier type demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_types_local" model="courier.type"> |
||||
|
<field name="courier_type">Local</field> |
||||
|
</record> |
||||
|
<record id="courier_types_parsel" model="courier.type"> |
||||
|
<field name="courier_type">Parsel</field> |
||||
|
</record> |
||||
|
<record id="courier_types_expense" model="courier.type"> |
||||
|
<field name="courier_type">Expense</field> |
||||
|
</record> |
||||
|
<record id="courier_types_non_expense" model="courier.type"> |
||||
|
<field name="courier_type">Non Expense</field> |
||||
|
</record> |
||||
|
<record id="courier_types_metals" model="courier.type"> |
||||
|
<field name="courier_type">Metals</field> |
||||
|
</record> |
||||
|
<record id="courier_types_non_metals" model="courier.type"> |
||||
|
<field name="courier_type">Non Metals</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,72 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier weight price demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_weight_price_rule_1_to_5" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 1 To 5 Kilograms</field> |
||||
|
<field name="minimum_weight">1</field> |
||||
|
<field name="maximum_weight">5</field> |
||||
|
<field name="price">15</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_5_to_10" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 5 To 10 Kilograms</field> |
||||
|
<field name="minimum_weight">5</field> |
||||
|
<field name="maximum_weight">10</field> |
||||
|
<field name="price">25</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_5_to_15" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 5 To 15 Kilograms</field> |
||||
|
<field name="minimum_weight">5</field> |
||||
|
<field name="maximum_weight">15</field> |
||||
|
<field name="price">30</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_1_to_15" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 1 To 15 Kilograms</field> |
||||
|
<field name="minimum_weight">1</field> |
||||
|
<field name="maximum_weight">15</field> |
||||
|
<field name="price">9</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_15_to_20" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 15 To 20 Kilograms</field> |
||||
|
<field name="minimum_weight">15</field> |
||||
|
<field name="maximum_weight">20</field> |
||||
|
<field name="price">40</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_15_to_25" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 15 To 25 Kilograms</field> |
||||
|
<field name="minimum_weight">15</field> |
||||
|
<field name="maximum_weight">25</field> |
||||
|
<field name="price">45</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_20_to_30" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 20 To 30 Kilograms</field> |
||||
|
<field name="minimum_weight">20</field> |
||||
|
<field name="maximum_weight">30</field> |
||||
|
<field name="price">50</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_30_to_50" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 30 To 50 Kilograms</field> |
||||
|
<field name="minimum_weight">30</field> |
||||
|
<field name="maximum_weight">50</field> |
||||
|
<field name="price">100</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_30_to_40" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 30 To 40 Kilograms</field> |
||||
|
<field name="minimum_weight">30</field> |
||||
|
<field name="maximum_weight">40</field> |
||||
|
<field name="price">70</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_40_to_50" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 40 To 50 Kilograms</field> |
||||
|
<field name="minimum_weight">40</field> |
||||
|
<field name="maximum_weight">50</field> |
||||
|
<field name="price">99</field> |
||||
|
</record> |
||||
|
<record id="courier_weight_price_rule_01_to_1" model="courier.weight.price"> |
||||
|
<field name="name">If Weight 0.01 To 1 Kilograms</field> |
||||
|
<field name="minimum_weight">0.01</field> |
||||
|
<field name="maximum_weight">1</field> |
||||
|
<field name="price">5</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,34 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- Product product demo data--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="additional_charges_priority_product" |
||||
|
model="product.product"> |
||||
|
<field name="name">Additional Charges</field> |
||||
|
<field name="default_code">COURIER 001</field> |
||||
|
<field name="list_price">0.00</field> |
||||
|
<field name="type">consu</field> |
||||
|
<field name="active" eval="False"/> |
||||
|
<field name="sale_ok">False</field> |
||||
|
<field name="purchase_ok">False</field> |
||||
|
</record> |
||||
|
<record id="distance_charges_product" model="product.product"> |
||||
|
<field name="name">Distance Charges</field> |
||||
|
<field name="default_code">COURIER 002</field> |
||||
|
<field name="list_price">0.00</field> |
||||
|
<field name="type">consu</field> |
||||
|
<field name="active" eval="False"/> |
||||
|
<field name="sale_ok">False</field> |
||||
|
<field name="purchase_ok">False</field> |
||||
|
</record> |
||||
|
<record id="volumetric_weight_charges_product" model="product.product"> |
||||
|
<field name="name">Volumetric Weight Charges</field> |
||||
|
<field name="default_code">COURIER 003</field> |
||||
|
<field name="list_price">0.00</field> |
||||
|
<field name="type">consu</field> |
||||
|
<field name="active" eval="False"/> |
||||
|
<field name="sale_ok">False</field> |
||||
|
<field name="purchase_ok">False</field> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,6 @@ |
|||||
|
## Module <courier_management> |
||||
|
|
||||
|
#### 17.04.2025 |
||||
|
#### Version 18.0.1.0.0 |
||||
|
#### ADD |
||||
|
- Initial commit for Courier Management |
@ -0,0 +1,31 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from . import account_move |
||||
|
from . import courier_category |
||||
|
from . import courier_detail |
||||
|
from . import courier_dimension_price |
||||
|
from . import courier_distance_price |
||||
|
from . import courier_priority |
||||
|
from . import courier_request |
||||
|
from . import courier_tag |
||||
|
from . import courier_type |
||||
|
from . import courier_weight_price |
@ -0,0 +1,31 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class AccountMove(models.Model): |
||||
|
"""This is for adding courier sequence number to invoice""" |
||||
|
_inherit = 'account.move' |
||||
|
|
||||
|
courier_ref_id = fields.Many2one('courier.request', string="Courier", |
||||
|
readonly=True, help="Shows the courier " |
||||
|
"reference") |
@ -0,0 +1,32 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class CourierCategory(models.Model): |
||||
|
"""This is for creating courier category""" |
||||
|
_name = 'courier.category' |
||||
|
_description = "Courier Category" |
||||
|
_rec_name = 'courier_category' |
||||
|
|
||||
|
courier_category = fields.Char(string="Courier Category", required=True, |
||||
|
help="Choose the courier category") |
@ -0,0 +1,87 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models |
||||
|
|
||||
|
|
||||
|
class CourierDetail(models.Model): |
||||
|
"""This is the order line of courier requests""" |
||||
|
_name = 'courier.detail' |
||||
|
_description = "Courier Detail" |
||||
|
_rec_name = 'product_id' |
||||
|
|
||||
|
product_id = fields.Many2one('product.product', string="Product", |
||||
|
required=True, help="Courier product name") |
||||
|
quantity = fields.Integer(string="Quantity", required=True, default=1, |
||||
|
help="Quantity of the courier product") |
||||
|
weight = fields.Float(string="Weight", related='product_id.weight', |
||||
|
help="Weight of the courier product") |
||||
|
total_weight = fields.Float(string="Total Weight", |
||||
|
compute='_compute_total_weight', |
||||
|
help="Total weight of the courier product") |
||||
|
weight_price = fields.Float(string="Weight Price", readonly=True, |
||||
|
help="Product weight price") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Choose company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
sub_total = fields.Monetary(string="Sub Total", |
||||
|
compute='_compute_sub_total', |
||||
|
help="Get the total amount") |
||||
|
courier_requests_id = fields.Many2one('courier.request', |
||||
|
string="Courier Request", |
||||
|
help="Relational field of courier " |
||||
|
"request") |
||||
|
|
||||
|
@api.depends('weight', 'quantity') |
||||
|
def _compute_total_weight(self): |
||||
|
"""It will compute the total weight""" |
||||
|
for record in self: |
||||
|
record.total_weight = record.quantity * record.weight \ |
||||
|
if record.quantity else record.weight |
||||
|
prices = [] |
||||
|
record.weight_price = False |
||||
|
for rec in self.env['courier.weight.price'].search( |
||||
|
[('minimum_weight', '<=', record.total_weight), |
||||
|
('maximum_weight', '>=', record.total_weight)]): |
||||
|
prices.append(rec.price) |
||||
|
if prices: |
||||
|
record.weight_price = min(prices) |
||||
|
else: |
||||
|
minimum = [] |
||||
|
maximum = [] |
||||
|
price = [] |
||||
|
for records in self.env['courier.weight.price'].search([]): |
||||
|
minimum.append(records.minimum_weight) |
||||
|
maximum.append(records.maximum_weight) |
||||
|
price.append(records.price) |
||||
|
if record.total_weight < min(minimum): |
||||
|
record.weight_price = min(price) |
||||
|
elif record.total_weight > max(maximum): |
||||
|
record.weight_price = max(price) |
||||
|
|
||||
|
@api.depends('quantity', 'product_id') |
||||
|
def _compute_sub_total(self): |
||||
|
"""Compute the sub-total of courier requests""" |
||||
|
for record in self: |
||||
|
record.sub_total = record.weight_price |
@ -0,0 +1,62 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class CourierDimensionPrice(models.Model): |
||||
|
"""This is for creating courier dimension price rule""" |
||||
|
_name = 'courier.dimension.price' |
||||
|
_description = "Courier Dimension PriceRule" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True, |
||||
|
help="Name of courier dimension price") |
||||
|
length = fields.Integer(string="Length", required=True, |
||||
|
help="Length of box") |
||||
|
width = fields.Integer(string="Width", required=True, help="Width of box") |
||||
|
height = fields.Integer(string="Height", required=True, |
||||
|
help="Height of box") |
||||
|
volumetric_weight = fields.Float(string="Volumetric Weight(kg)", |
||||
|
compute='_compute_volumetric_weight', |
||||
|
help="Weight of the courier") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Choose company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
price = fields.Monetary(string="Price", required=True, |
||||
|
help="The price based on weight") |
||||
|
|
||||
|
@api.constrains('length', 'width', 'height') |
||||
|
def _check_available_combinations(self): |
||||
|
"""Returns validation based on length, width and height""" |
||||
|
if self.length <= 0 or self.width <= 0 or self.height <= 0: |
||||
|
raise ValidationError(_('Invalid Combination')) |
||||
|
|
||||
|
@api.depends('length', 'width', 'height') |
||||
|
def _compute_volumetric_weight(self): |
||||
|
"""Compute the volumetric weight of courier""" |
||||
|
for rec in self: |
||||
|
rec.volumetric_weight = (rec.length * rec.width * rec.height) / \ |
||||
|
5000 |
@ -0,0 +1,56 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class CourierDistancePrice(models.Model): |
||||
|
"""This is for creating courier distance price rule""" |
||||
|
_name = 'courier.distance.price' |
||||
|
_description = "Courier Distance PriceRule" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True, |
||||
|
help="Name of courier distance price rule") |
||||
|
minimum_distance = fields.Float(string="Minimum Distance", required=True, |
||||
|
help="Minimum distance for delivery") |
||||
|
maximum_distance = fields.Float(string="Maximum Distance", required=True, |
||||
|
help="Maximum distance for delivery") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Current company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
price = fields.Monetary(string="Price", required=True, |
||||
|
help="Price based on the distance") |
||||
|
|
||||
|
@api.constrains('maximum_distance', 'minimum_distance') |
||||
|
def _check_distance(self): |
||||
|
"""Returns validation based on distance""" |
||||
|
if self.minimum_distance <= 0 or self.maximum_distance <= 0: |
||||
|
raise ValidationError(_('Delivery is not possible')) |
||||
|
if self.minimum_distance == 0 or self.maximum_distance == 0: |
||||
|
raise ValidationError(_('Invalid Distance')) |
||||
|
if self.minimum_distance > self.maximum_distance: |
||||
|
raise ValidationError( |
||||
|
_('Minimum Distance must be less than Maximum Distance')) |
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class CourierPriority(models.Model): |
||||
|
"""This is for creating courier priority""" |
||||
|
_name = 'courier.priority' |
||||
|
_description = "Courier Priority" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True, help="The priority name") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Choose company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
charges = fields.Monetary(string="Charges", required=True, |
||||
|
help="Priority charges") |
@ -0,0 +1,359 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from datetime import date |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class CourierRequest(models.Model): |
||||
|
"""This is for creating courier requests""" |
||||
|
_name = 'courier.request' |
||||
|
_description = "Courier Request" |
||||
|
_inherit = ["mail.thread", "mail.activity.mixin"] |
||||
|
|
||||
|
state = fields.Selection( |
||||
|
selection=[('new', 'New'), ('collected', 'Collected'), |
||||
|
('invoiced', 'Invoiced'), ('dispatched', 'Dispatched'), |
||||
|
('in_transit', 'In Transit'), |
||||
|
('arrived_at_destination', 'Arrived At Destination'), |
||||
|
('out_for_delivery', 'Out For Delivery'), |
||||
|
('delivered', 'Delivered'), ('cancelled', 'Cancelled')], |
||||
|
string="State", default='new', help="State of the courier request") |
||||
|
name = fields.Char(string='Name', readonly=True, copy=False, |
||||
|
default='New', help="Sequence number") |
||||
|
sender_id = fields.Many2one('res.partner', |
||||
|
string="Sender Name", |
||||
|
help="Name of The Sender", required=True) |
||||
|
sender_address = fields.Char(string="Sender Address", |
||||
|
help="Address Of The Sender") |
||||
|
sender_mobile_number = fields.Char(string="Sender Phone Number", |
||||
|
help="Mobile Number Of The Sender", |
||||
|
related='sender_id.phone', |
||||
|
readonly=False, |
||||
|
required=True) |
||||
|
sender_email = fields.Char(string="Sender Email", |
||||
|
help="Email Of The Sender", |
||||
|
related='sender_id.email', |
||||
|
readonly=False, required=True) |
||||
|
sender_street = fields.Char(string="Sender Street", |
||||
|
related='sender_id.street', readonly=False, |
||||
|
help="Street of the sender") |
||||
|
sender_street2 = fields.Char(string="Sender Second Street", |
||||
|
related='sender_id.street2', readonly=False, |
||||
|
help="Second street of the sender") |
||||
|
sender_city = fields.Char(string="Sender City", related='sender_id.city', |
||||
|
readonly=False, |
||||
|
help="City of the sender") |
||||
|
sender_state_id = fields.Many2one('res.country.state', |
||||
|
string="Sender State", |
||||
|
related='sender_id.state_id', |
||||
|
readonly=False, |
||||
|
domain="[('country_id', '=?', " |
||||
|
"sender_address_country_id)]", |
||||
|
help="State of the sender") |
||||
|
sender_zip = fields.Char(string="Sender Zip", related='sender_id.zip', |
||||
|
help="Zip of the sender") |
||||
|
sender_address_country_id = fields.Many2one('res.country', |
||||
|
string="Sender Country " |
||||
|
"Address", |
||||
|
related='sender_id.country_id', |
||||
|
readonly=False, |
||||
|
help="Country of the sender") |
||||
|
receiver_id = fields.Many2one('res.partner', |
||||
|
string="Receiver Name", |
||||
|
help="Name of the receiver", required=True) |
||||
|
receiver_address = fields.Char(string="Receiver Address", |
||||
|
help="Address of the receiver") |
||||
|
receiver_street = fields.Char(string="Receiver Street", |
||||
|
related='receiver_id.street', readonly=False, |
||||
|
help="Street of the receiver") |
||||
|
receiver_street2 = fields.Char(string="Receiver Second Street", |
||||
|
related='receiver_id.street2', |
||||
|
readonly=False, |
||||
|
help="Second street of the receiver") |
||||
|
receiver_city = fields.Char(string="Receiver City", |
||||
|
related='receiver_id.city', readonly=False, |
||||
|
help="City of the receiver") |
||||
|
receiver_state_id = fields.Many2one('res.country.state', |
||||
|
string="Receiver State", |
||||
|
related='receiver_id.state_id', |
||||
|
readonly=False, |
||||
|
domain="[('country_id', '=?', " |
||||
|
"receiver_address_country_id)]", |
||||
|
help="State of the receiver") |
||||
|
receiver_zip = fields.Char(string="Receiver Zip", |
||||
|
related='receiver_id.zip', |
||||
|
readonly=False, |
||||
|
help="Zip of the receiver") |
||||
|
receiver_address_country_id = fields.Many2one('res.country', |
||||
|
string="Receiver Country " |
||||
|
"Address", |
||||
|
related='receiver_id.' |
||||
|
'country_id', |
||||
|
readonly=False, |
||||
|
help="Country of the " |
||||
|
"receiver") |
||||
|
receiver_mobile_number = fields.Char(string="Receiver Phone Number", |
||||
|
help="Mobile Number Of The Receiver", |
||||
|
related='receiver_id.phone', |
||||
|
readonly=False, |
||||
|
required=True) |
||||
|
receiver_email = fields.Char(string="Receiver Email", help="Email Of The " |
||||
|
"Receiver", |
||||
|
related='receiver_id.email', |
||||
|
readonly=False, required=True) |
||||
|
registration_date = fields.Date(string="Registration Date", |
||||
|
help="Courier Registration Date", |
||||
|
default=date.today(), |
||||
|
readonly=True) |
||||
|
delivery_date = fields.Date(string="Delivery Date", |
||||
|
help="Courier Delivery Date", required=True) |
||||
|
total_kilometres = fields.Float(string="Total Kilometres", |
||||
|
help="Total Kilometers To Courier Sends", |
||||
|
required=True) |
||||
|
distance_amount = fields.Monetary(string="Distance Amount", |
||||
|
compute='_compute_distance_amount', |
||||
|
store=True, |
||||
|
help="Distance amount based on the " |
||||
|
"distance") |
||||
|
responsible_user_id = fields.Many2one('res.users', |
||||
|
default=lambda self: self.env.user, |
||||
|
string="Responsible User", |
||||
|
help="Responsible User Of This " |
||||
|
"Courier", |
||||
|
readonly=True) |
||||
|
type_id = fields.Many2one('courier.type', string="Type", |
||||
|
required=True, help="Courier type") |
||||
|
tag_ids = fields.Many2many('courier.tag', string="Tag", |
||||
|
help="Courier tags") |
||||
|
l_w_h_id = fields.Many2one('courier.dimension.price', |
||||
|
string="L x W x H", required=True, |
||||
|
help="Courier box size") |
||||
|
volumetric_weight = fields.Float(string="Volumetric Weight", |
||||
|
related='l_w_h_id.volumetric_weight', |
||||
|
help="Weight of the courier") |
||||
|
volumetric_weight_price = fields.Monetary(string="Volumetric Weight Price", |
||||
|
compute='_compute_volumetric_' |
||||
|
'weight_price', |
||||
|
help="Weight price of the" |
||||
|
" courier") |
||||
|
priority_id = fields.Many2one('courier.priority', |
||||
|
string="Priority", help="Courier priority") |
||||
|
priority_amount = fields.Monetary(string="Priority Amount", |
||||
|
compute='_compute_priority_amount', |
||||
|
help="Courier priority amount based on " |
||||
|
"priority") |
||||
|
category_id = fields.Many2one('courier.category', |
||||
|
string="Category", required=True, |
||||
|
help="Courier category") |
||||
|
description = fields.Char(string="Description", help="Add description") |
||||
|
internal_note = fields.Char(string="Internal Note", help="Add internal " |
||||
|
"note") |
||||
|
total_courier_charges = fields.Float(string="Total Courier Charges", |
||||
|
readonly=True, |
||||
|
help="The total courier charges") |
||||
|
total = fields.Monetary(string="Total", compute='_compute_total', |
||||
|
help="Total") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Choose company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
courier_details_ids = fields.One2many('courier.detail', |
||||
|
'courier_requests_id', |
||||
|
string="Courier Details", |
||||
|
help="Courier details") |
||||
|
|
||||
|
def action_collected(self): |
||||
|
"""This will change the state to collected or give validation error""" |
||||
|
for record in self: |
||||
|
if record.courier_details_ids: |
||||
|
self.state = 'collected' |
||||
|
else: |
||||
|
raise ValidationError(_( |
||||
|
'You Need To Add A Line Before Collecting')) |
||||
|
|
||||
|
def action_dispatched(self): |
||||
|
"""This will change the state to dispatched""" |
||||
|
self.state = 'dispatched' |
||||
|
|
||||
|
def action_in_transit(self): |
||||
|
"""This will change the state to in transit""" |
||||
|
self.state = 'in_transit' |
||||
|
|
||||
|
def action_arrived_at_destination(self): |
||||
|
"""This will change the state to arrived at destination""" |
||||
|
self.state = 'arrived_at_destination' |
||||
|
|
||||
|
def action_out_for_delivery(self): |
||||
|
"""This will change the state to out for delivery""" |
||||
|
self.state = 'out_for_delivery' |
||||
|
|
||||
|
def action_delivered(self): |
||||
|
"""This will change the state to delivered""" |
||||
|
self.state = 'delivered' |
||||
|
|
||||
|
def action_cancelled(self): |
||||
|
"""This will change the state to cancelled""" |
||||
|
self.state = 'cancelled' |
||||
|
|
||||
|
@api.onchange('delivery_date') |
||||
|
def _onchange_delivery_date(self): |
||||
|
"""If the delivery date is smaller than registration date. It gives |
||||
|
a validation error""" |
||||
|
if self.delivery_date and self.delivery_date <= self.registration_date: |
||||
|
raise ValidationError(_('Delivery Is Not Possible On This Date')) |
||||
|
|
||||
|
@api.onchange('total_kilometres') |
||||
|
def _onchange_total_kilometres(self): |
||||
|
"""If the total kilometres is smaller than one.It gives a validation""" |
||||
|
if self.total_kilometres and self.total_kilometres < 1: |
||||
|
raise ValidationError(_('Delivery Is Not Available')) |
||||
|
|
||||
|
def action_create_invoice(self): |
||||
|
"""Creating invoices for corresponding courier request""" |
||||
|
self.state = 'invoiced' |
||||
|
for rec in self: |
||||
|
invoice_id = self.env['account.move'].create({ |
||||
|
'move_type': 'out_invoice', |
||||
|
'partner_id': rec.sender_id.id, |
||||
|
'invoice_date': rec.registration_date, |
||||
|
'invoice_user_id': rec.responsible_user_id.id, |
||||
|
'courier_ref_id': rec.id |
||||
|
}) |
||||
|
for courier_order_line in self.courier_details_ids: |
||||
|
invoice_id.write({ |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'product_id': courier_order_line.product_id.id, |
||||
|
'quantity': 1, |
||||
|
'price_unit': courier_order_line.weight_price, |
||||
|
})] |
||||
|
}) |
||||
|
if self.l_w_h_id: |
||||
|
invoice_id.write({ |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'product_id': self.env.ref( |
||||
|
'courier_management.' |
||||
|
'volumetric_weight_charges_product').id, |
||||
|
})] |
||||
|
}) |
||||
|
if self.priority_id: |
||||
|
invoice_id.write({ |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'product_id': self.env.ref( |
||||
|
'courier_management.' |
||||
|
'additional_charges_priority_product').id, |
||||
|
})] |
||||
|
}) |
||||
|
if self.distance_amount: |
||||
|
invoice_id.write({ |
||||
|
'invoice_line_ids': [(0, 0, { |
||||
|
'product_id': self.env.ref( |
||||
|
'courier_management.distance_charges_product').id, |
||||
|
})] |
||||
|
}) |
||||
|
invoice_id.action_post() |
||||
|
|
||||
|
def action_view_invoices(self): |
||||
|
"""It returns the Invoices tree view""" |
||||
|
return { |
||||
|
'name': 'Invoice', |
||||
|
'view_mode': 'list,form', |
||||
|
'res_model': 'account.move', |
||||
|
'type': 'ir.actions.act_window', |
||||
|
'domain': [('courier_ref_id', '=', self.id)], |
||||
|
'context': "{'create': False}" |
||||
|
} |
||||
|
|
||||
|
@api.onchange('courier_details_ids') |
||||
|
def _onchange_courier_details_ids(self): |
||||
|
"""Returns the total courier charges""" |
||||
|
total = 0 |
||||
|
courier = self.courier_details_ids |
||||
|
total_charge = courier.mapped('sub_total') |
||||
|
for record in range(0, len(total_charge)): |
||||
|
total = total + total_charge[record] |
||||
|
self.total_courier_charges = total |
||||
|
|
||||
|
@api.depends('priority_amount', 'distance_amount', |
||||
|
'total_courier_charges', 'volumetric_weight_price') |
||||
|
def _compute_total(self): |
||||
|
"""Computes the total""" |
||||
|
self.total = (self.priority_amount + self.distance_amount |
||||
|
+ self.total_courier_charges + |
||||
|
self.volumetric_weight_price) |
||||
|
|
||||
|
@api.depends('total_kilometres') |
||||
|
def _compute_distance_amount(self): |
||||
|
"""Returns the distance amount""" |
||||
|
prices = [] |
||||
|
self.distance_amount = False |
||||
|
for record in self.env['courier.distance.price'].search( |
||||
|
[('minimum_distance', '<=', self.total_kilometres), |
||||
|
('maximum_distance', '>=', self.total_kilometres)]): |
||||
|
prices.append(record.price) |
||||
|
if prices: |
||||
|
self.distance_amount = min(prices) |
||||
|
else: |
||||
|
distances = self.env['courier.distance.price'].search([]) |
||||
|
minimum_distances = [rec.minimum_distance for rec in distances] |
||||
|
maximum_distances = [rec.maximum_distance for rec in distances] |
||||
|
prices = [rec.price for rec in distances] |
||||
|
|
||||
|
if self.total_kilometres < min(minimum_distances): |
||||
|
self.distance_amount = min(prices) |
||||
|
elif self.total_kilometres > max(maximum_distances): |
||||
|
self.distance_amount = max(prices) |
||||
|
|
||||
|
distance = self.env['product.product'].browse( |
||||
|
[self.env.ref('courier_management.distance_charges_product').id]) |
||||
|
distance.list_price = self.distance_amount |
||||
|
|
||||
|
@api.depends('priority_id') |
||||
|
def _compute_priority_amount(self): |
||||
|
"""Returns the priority amount based on priority""" |
||||
|
self.priority_amount = self.priority_id.charges |
||||
|
priority = self.env['product.product'].browse( |
||||
|
[self.env.ref( |
||||
|
'courier_management.additional_charges_priority_product').id]) |
||||
|
priority.list_price = self.priority_amount |
||||
|
|
||||
|
@api.depends('l_w_h_id') |
||||
|
def _compute_volumetric_weight_price(self): |
||||
|
"""Returns the volumetric weight price""" |
||||
|
self.volumetric_weight_price = self.l_w_h_id.price |
||||
|
volume = self.env['product.product'].browse( |
||||
|
[self.env.ref( |
||||
|
'courier_management.volumetric_weight_charges_product').id]) |
||||
|
volume.list_price = self.volumetric_weight_price |
||||
|
|
||||
|
@api.model_create_multi |
||||
|
def create(self, vals_list): |
||||
|
"""This is used to get the Courier sequence number""" |
||||
|
for vals in vals_list: |
||||
|
if vals.get('name', 'New') == 'New': |
||||
|
vals['name'] = self.env['ir.sequence'].next_by_code( |
||||
|
'courier.request') or 'New' |
||||
|
result = super(CourierRequest, self).create(vals_list) |
||||
|
return result |
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from random import randint |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class CourierTag(models.Model): |
||||
|
"""This is for creating courier tags""" |
||||
|
_name = 'courier.tag' |
||||
|
_description = "Courier Tag" |
||||
|
_rec_name = 'courier_tags' |
||||
|
|
||||
|
def _get_default_color(self): |
||||
|
"""It returns the color""" |
||||
|
return randint(1, 11) |
||||
|
|
||||
|
courier_tags = fields.Char(string="Courier Tag", required=True, |
||||
|
help="Tags") |
||||
|
color = fields.Integer(string="Color", default=_get_default_color, |
||||
|
help="Color of tag") |
@ -0,0 +1,32 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class CourierType(models.Model): |
||||
|
"""This is for creating courier type""" |
||||
|
_name = 'courier.type' |
||||
|
_description = "Courier Type" |
||||
|
_rec_name = 'courier_type' |
||||
|
|
||||
|
courier_type = fields.Char(string="Type", required=True, |
||||
|
help="Type of the courier") |
@ -0,0 +1,54 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################### |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2025-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Cybrosys Techno Solutions (<https://www.cybrosys.com>) |
||||
|
# |
||||
|
# This program is under the terms of Odoo Proprietary License v1.0 (OPL-1) |
||||
|
# It is forbidden to publish, distribute, sublicense, or sell copies of the |
||||
|
# Software or modified copies of the Software. |
||||
|
# |
||||
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL |
||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER |
||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING |
||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
|
# DEALINGS IN THE SOFTWARE. |
||||
|
# |
||||
|
############################################################################### |
||||
|
from odoo import api, fields, models, _ |
||||
|
from odoo.exceptions import ValidationError |
||||
|
|
||||
|
|
||||
|
class CourierWeightPrice(models.Model): |
||||
|
"""This is for creating courier weight price rule""" |
||||
|
_name = 'courier.weight.price' |
||||
|
_description = "Courier Weight PriceRule" |
||||
|
|
||||
|
name = fields.Char(string="Name", required=True, |
||||
|
help="Name of courier weight price rule") |
||||
|
minimum_weight = fields.Float(string="Minimum Weight", required=True, |
||||
|
help="Minimum weight") |
||||
|
maximum_weight = fields.Float(string="Maximum Weight", required=True, |
||||
|
help="Maximum weight") |
||||
|
company_id = fields.Many2one('res.company', string="Company", |
||||
|
required=True, |
||||
|
default=lambda self: self.env.company, |
||||
|
readonly=True, help="Choose company") |
||||
|
currency_id = fields.Many2one("res.currency", string='Currency', |
||||
|
related='company_id.currency_id', |
||||
|
help="Company currency") |
||||
|
price = fields.Monetary(string="Price", required=True, |
||||
|
help="The price based on courier weight") |
||||
|
|
||||
|
@api.constrains('maximum_weight', 'minimum_weight') |
||||
|
def _check_weight(self): |
||||
|
"""Returns validations based on the weight""" |
||||
|
if self.minimum_weight <= 0 or self.maximum_weight <= 0: |
||||
|
raise ValidationError(_('Weight must be greater than zero')) |
||||
|
if self.minimum_weight >= self.maximum_weight: |
||||
|
raise ValidationError( |
||||
|
_('Minimum Weight must be less than Maximum Weight')) |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier requests report actions--> |
||||
|
<record id="action_courier_request_report" model="ir.actions.report"> |
||||
|
<field name="name">Courier Request Report</field> |
||||
|
<field name="model">courier.request</field> |
||||
|
<field name="report_type">qweb-pdf</field> |
||||
|
<field name="report_name">courier_management.report_courier_request</field> |
||||
|
<field name="report_file">courier_management.report_courier_request</field> |
||||
|
<field name="binding_model_id" ref="model_courier_request"/> |
||||
|
<field name="binding_type">report</field> |
||||
|
<field name="binding_view_types">form</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,257 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<odoo> |
||||
|
<!-- Courier requests pdf template--> |
||||
|
<template id="report_courier_request"> |
||||
|
<t t-call="web.html_container"> |
||||
|
<t t-call="web.external_layout"> |
||||
|
<div class="page"> |
||||
|
<t t-foreach="docs" t-as="doc"> |
||||
|
<h1 style="color:black;align:center">Courier Request |
||||
|
Report |
||||
|
</h1> |
||||
|
<table class="table"> |
||||
|
<tr> |
||||
|
<h2 style="color:black"> |
||||
|
<t t-esc="doc['name']"/> |
||||
|
</h2> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<table class="table"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Sender Name</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['sender_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Sender Mobile Number</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['sender_mobile_number']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Sender Email</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['sender_email']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Receiver Name</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['receiver_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Receiver Mobile Number</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['receiver_mobile_number']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Receiver Email</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['receiver_email']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Registration Date</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['registration_date']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Delivery Date</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['delivery_date']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Total Kilometres</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['total_kilometres']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Distance Amount</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['distance_amount']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>L x W x H</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['l_w_h_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Volumetric Weight</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['volumetric_weight']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Volumetric Weight Price</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['volumetric_weight_price']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Priority</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['priority_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Priority Amount</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['priority_amount']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Type</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['type_id'].courier_type"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
|
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Category</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['category_id'].courier_category"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Responsible User</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['responsible_user_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Company</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['company_id'].name"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<h5 style="color:black;align:center">Courier Details |
||||
|
</h5> |
||||
|
<table class="table table-sm o_main_table"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Product</th> |
||||
|
<th>Quantity</th> |
||||
|
<th>Weight</th> |
||||
|
<th>Total Weight</th> |
||||
|
<th>Weight Price</th> |
||||
|
<th>Sub Total</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
<t t-foreach="doc['courier_details_ids']" |
||||
|
t-as="details"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<t t-esc="details['product_id'].name"/> |
||||
|
</td> |
||||
|
|
||||
|
<td> |
||||
|
<t t-esc="details['quantity']"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="details['weight']"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="details['total_weight']"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="details['weight_price']"/> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="details['sub_total']"/> |
||||
|
</td> |
||||
|
|
||||
|
</tr> |
||||
|
</t> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
<br/> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Description</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['description']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<br/> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<strong>Internal Note</strong> |
||||
|
</td> |
||||
|
<td> |
||||
|
<t t-esc="doc['internal_note']"/> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<br/> |
||||
|
<br/> |
||||
|
<div style="margin-left:550px"> |
||||
|
<td> |
||||
|
<h7>Total Courier Charges: |
||||
|
<t t-esc="doc['total_courier_charges']"/> |
||||
|
</h7> |
||||
|
</td> |
||||
|
<br/> |
||||
|
<td> |
||||
|
<h7 style="font-size: 1.19166667rem;font-weight: revert;"> |
||||
|
Total: |
||||
|
<t t-esc="doc['total']"/> |
||||
|
</h7> |
||||
|
</td> |
||||
|
</div> |
||||
|
</t> |
||||
|
</div> |
||||
|
</t> |
||||
|
</t> |
||||
|
</template> |
||||
|
</odoo> |
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Courier management groups--> |
||||
|
<data noupdate="0"> |
||||
|
<record id="courier_management" model="ir.module.category"> |
||||
|
<field name="name">Courier Management</field> |
||||
|
<field name="description">Access For Courier Management Module</field> |
||||
|
<field name="sequence">11</field> |
||||
|
</record> |
||||
|
<record id="courier_management_group_user" model="res.groups"> |
||||
|
<field name="name">User</field> |
||||
|
<field name="category_id" ref="courier_management.courier_management"/> |
||||
|
</record> |
||||
|
<record id="courier_management_group_administrator" model="res.groups"> |
||||
|
<field name="name">Administrator</field> |
||||
|
<field name="category_id" ref="courier_management.courier_management"/> |
||||
|
<field name="implied_ids" |
||||
|
eval="[(4, ref('courier_management_group_user'))]"/> |
||||
|
</record> |
||||
|
<record id="base.default_user" model="res.users"> |
||||
|
<field name="groups_id" |
||||
|
eval="[(4,ref('courier_management_group_administrator'))]"/> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,31 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!-- Courier requests record rule--> |
||||
|
<data noupdate="1"> |
||||
|
<record id="courier_requests_rule_administrator" model="ir.rule"> |
||||
|
<field name="name">Courier Requests Administrator</field> |
||||
|
<field ref="model_courier_request" name="model_id"/> |
||||
|
<field name="domain_force">[(1,'=',1)]</field> |
||||
|
<field name="groups" |
||||
|
eval="[(4, ref('courier_management.courier_management_group_administrator'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
<record id="courier_requests_rule_user" model="ir.rule"> |
||||
|
<field name="name">Courier Requests User</field> |
||||
|
<field ref="model_courier_request" name="model_id"/> |
||||
|
<field name="domain_force">[('sender_id','=',user.partner_id.id)] |
||||
|
</field> |
||||
|
<field name="groups" |
||||
|
eval="[(4, ref('courier_management.courier_management_group_user'))]"/> |
||||
|
<field name="perm_read" eval="True"/> |
||||
|
<field name="perm_write" eval="True"/> |
||||
|
<field name="perm_create" eval="True"/> |
||||
|
<field name="perm_unlink" eval="True"/> |
||||
|
<field name="active" eval="True"/> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 393 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 912 KiB |