@ -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 |