Introduce classes and automatic weight/destination based pricing

The user now simply chooses 'registered letter' or 'letter' and the
calculator determines whihc type of product and what amount of franking
is required.
This commit is contained in:
Harald Welte 2016-07-15 20:27:56 +02:00
parent d6331f83e2
commit 3cb3683a8b
5 changed files with 230 additions and 24 deletions

View File

@ -7,7 +7,7 @@
<field name="code">20</field>
<field name="cost_price">0.70</field>
<field name="weight">0.020</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_kb" model="delivery.carrier.dp.service">
<field name="name">Kompaktbrief</field>
@ -15,7 +15,7 @@
<field name="code">11</field>
<field name="cost_price">0.85</field>
<field name="weight">0.050</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_gb" model="delivery.carrier.dp.service">
<field name="name">Großbrief</field>
@ -23,7 +23,7 @@
<field name="code">21</field>
<field name="cost_price">1.45</field>
<field name="weight">0.500</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_mb1k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief</field>
@ -31,7 +31,7 @@
<field name="code">31</field>
<field name="cost_price">2.60</field>
<field name="weight">1.000</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_mb2k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief bis 2000 g + Zusatzentgelt MBf</field>
@ -39,17 +39,25 @@
<field name="code">41</field>
<field name="cost_price">4.80</field>
<field name="weight">2.000</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_kb_ein" model="delivery.carrier.dp.service">
<field name="name">Kompaktbrief Integral + EINSCHREIBEN</field>
<field name="short_name">Kompakt Natl EIN</field>
<field name="code">1017</field>
<field name="cost_price">3.95</field>
<field name="weight">0.050</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_gb_ein" model="delivery.carrier.dp.service">
<field name="name">Großbrief Integral + EINSCHREIBEN</field>
<field name="short_name">Gross Natl EIN</field>
<field name="code">1027</field>
<field name="cost_price">3.95</field>
<field name="weight">0.500</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_mb1k_ein" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Integral + EINSCHREIBEN</field>
@ -57,15 +65,25 @@
<field name="code">1037</field>
<field name="cost_price">5.10</field>
<field name="weight">1.000</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_mb2k_ein" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Integral + EINSCHREIBEN EINWURF + Zusatzentgelt MBf</field>
<field name="short_name">Maxi Natl 2kg EIN</field>
<field name="code">1042</field>
<field name="cost_price">6.95</field>
<field name="weight">2.000</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_gb_wurf" model="delivery.carrier.dp.service">
<field name="name">Großbrief Integral + EINSCHREIBEN EINWURF</field>
<field name="short_name">Gross Natl WURF</field>
<field name="code">1022</field>
<field name="cost_price">3.60</field>
<field name="weight">0.500</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_natl_mb1k_wurf" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Integral + EINSCHREIBEN EINWURF</field>
@ -73,17 +91,65 @@
<field name="code">1032</field>
<field name="cost_price">4.75</field>
<field name="weight">1.000</field>
<field name="international">False</field>
<field name="international">0</field>
</record>
<record forcecreate="True" id="dp_service_intl_sb" model="delivery.carrier.dp.service">
<field name="name">Standardbrief Intern. GK Integral + EINSCHREIBEN</field>
<field name="short_name">Standart Intl EIN</field>
<field name="code">11006</field>
<field name="cost_price">3.40</field>
<field name="weight">0.020</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_kb" model="delivery.carrier.dp.service">
<field name="name">Kompaktbrief Intern. GK</field>
<field name="short_name">Kompakt Intl</field>
<field name="code">10011</field>
<field name="cost_price">1.50</field>
<field name="weight">0.050</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_gb" model="delivery.carrier.dp.service">
<field name="name">Großbrief Intern. GK</field>
<field name="short_name">Gross Intl</field>
<field name="code">10051</field>
<field name="cost_price">3.70</field>
<field name="weight">0.500</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_mb1k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Intern. bis 1.000g GK</field>
<field name="short_name">Maxi Intl 1kg</field>
<field name="code">10071</field>
<field name="cost_price">7.00</field>
<field name="weight">1.000</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_mb2k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Intern. bis 2.000g GK</field>
<field name="short_name">Maxi Intl 2kg</field>
<field name="code">10091</field>
<field name="cost_price">17.00</field>
<field name="weight">2.000</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_sb_ein" model="delivery.carrier.dp.service">
<field name="name">Standardbrief Intern. GK Integral + EINSCHREIBEN</field>
<field name="short_name">Standart Intl EIN</field>
<field name="code">11006</field>
<field name="cost_price">3.40</field>
<field name="weight">0.020</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_kb_ein" model="delivery.carrier.dp.service">
<field name="name">Kompaktbrief Intern. GK Integral + EINSCHREIBEN</field>
<field name="short_name">Kompakt Intl EIN</field>
<field name="code">11016</field>
<field name="cost_price">4.00</field>
<field name="weight">0.050</field>
<field name="international">True</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_gb_ein" model="delivery.carrier.dp.service">
<field name="name">Großbrief Intern. GK Integral + EINSCHREIBEN</field>
@ -91,7 +157,7 @@
<field name="code">11056</field>
<field name="cost_price">6.20</field>
<field name="weight">0.500</field>
<field name="international">True</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_mb1k_ein" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Intern. bis 1.000g GK Integral + EINSCHREIBEN</field>
@ -99,7 +165,7 @@
<field name="code">11076</field>
<field name="cost_price">9.50</field>
<field name="weight">1.000</field>
<field name="international">True</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_service_intl_mb2k_ein" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Intern. bis 2.000g GK Integral + EINSCHREIBEN</field>
@ -107,8 +173,33 @@
<field name="code">11096</field>
<field name="cost_price">19.50</field>
<field name="weight">2.000</field>
<field name="international">True</field>
<field name="international">1</field>
</record>
<record forcecreate="True" id="dp_class_regular" model="delivery.carrier.dp.class">
<field name="name">Standard</field>
<field name="services_natl" eval="[(4, ref('dp_service_natl_sb')),
(4, ref('dp_service_natl_kb')),
(4, ref('dp_service_natl_gb')),
(4, ref('dp_service_natl_mb1k')),
(4, ref('dp_service_natl_mb2k'))]"/>
<field name="services_intl" eval="[(4, ref('dp_service_intl_sb')),
(4, ref('dp_service_intl_kb')),
(4, ref('dp_service_intl_gb')),
(4, ref('dp_service_intl_mb1k')),
(4, ref('dp_service_intl_mb2k'))]"/>
</record>
<record forcecreate="True" id="dp_class_registered" model="delivery.carrier.dp.class">
<field name="name">Registered</field>
<field name="services_natl" eval="[(4, ref('dp_service_natl_kb_ein')),
(4, ref('dp_service_natl_gb_ein')),
(4, ref('dp_service_natl_mb1k_ein')),
(4, ref('dp_service_natl_mb2k_ein'))]"/>
<field name="services_intl" eval="[(4, ref('dp_service_intl_sb_ein')),
(4, ref('dp_service_intl_kb_ein')),
(4, ref('dp_service_intl_gb_ein')),
(4, ref('dp_service_intl_mb1k_ein')),
(4, ref('dp_service_intl_mb2k_ein'))]"/>
</record>
</data>
</openerp>

View File

@ -15,21 +15,38 @@
<field name="standard_price">0.0</field>
<field name="list_price">0.0</field>
</record>
<record id="dp_delivery_carrier" model="delivery.carrier">
<field name="name">Deutsche Post Brief</field>
<record id="dp_delivery_carrier_regular" model="delivery.carrier">
<field name="name">Deutsche Post Letter</field>
<field name="normal_price">0</field>
<field name="delivery_type">dp</field>
<field name="partner_id" ref="res_partner_dp"/>
<field name="product_id" ref="product_product_delivery_dp"/>
<field name="dp_service_type" ref=""/>
<field name="dp_service_class" ref="dp_class_regular"/>
<field name="environment">test</field>
<field name="extra_service_price">0</field>
<field name="address_validator">False</field>
<field name="genrate_label">True</field>
<field name="void_shipment">False</field>
<field name="address_validator">0</field>
<field name="genrate_label">1</field>
<field name="void_shipment">0</field>
<field name="uom_id" ref="product.product_uom_kgm"/>
<field name="delivery_uom">KG</field>
<!-- <field name="image" type="base64" file="dp_delivery_carrier/static/src/img/logo-dp.png"/> -->
</record>
<record id="dp_delivery_carrier_registered" model="delivery.carrier">
<field name="name">Deutsche Post Registered Letter</field>
<field name="normal_price">0</field>
<field name="delivery_type">dp</field>
<field name="partner_id" ref="res_partner_dp"/>
<field name="product_id" ref="product_product_delivery_dp"/>
<field name="dp_service_class" ref="dp_class_registered"/>
<field name="environment">test</field>
<field name="extra_service_price">0</field>
<field name="address_validator">0</field>
<field name="genrate_label">1</field>
<field name="void_shipment">0</field>
<field name="uom_id" ref="product.product_uom_kgm"/>
<field name="delivery_uom">KG</field>
<!-- <field name="image" type="base64" file="dp_delivery_carrier/static/src/img/logo-dp.png"/> -->
</record>
</data>
</openerp>

View File

@ -77,17 +77,46 @@ class DPDeliveryCarrier(models.Model):
last = last,
address = addr)
def get_services_by_country(self, service_class, country_code):
if country_code == 'DE':
return service_class.services_natl
else:
return service_class.services_intl
# determine lowest-matching-max-weight service within same class
def get_service_by_class(self, recipient, weight, service_class):
services = self.get_services_by_country(service_class, recipient.country_id.code)
lowest_max_weight = 100000
lowest_service = None
for s in services:
if s.weight >= weight and s.weight < lowest_max_weight:
lowest_max_weight = s.weight
lowest_service = s
return lowest_service
# determine the maximum weight (in kg) of any service in this class
def get_class_max_weight(self, service_class):
services = self.get_services_by_country(service_class, recipient.country_id.code)
highest_weight = 0
for s in services:
if highest_weight > hightest_weight:
highest_weight = s.weight
return highest_weight
@api.one
def dp_send_shipping(self, pickings):
config = self._get_config()
order = self.env['sale.order'].search([('name','=',pickings.origin)])
recipient = pickings.partner_id
warehouse = pickings.picking_type_id.warehouse_id.partner_id
service = self.sudo().dp_service_type
weight = self._get_weight(order, pickings)
service = self.get_service_by_class(recipient, weight, self.sudo().dp_service_class)
if not service:
raise Warning("Service not available for weight!")
im = self.conn_auth_im()
im_recipient = self.build_im_addr(im, recipient)
im_sender = self.build_im_addr(im, warehouse)
service = self.sudo().dp_service_type
im.clear_positions()
position = im.build_position(service.code, im_sender, im_recipient)
im.add_position(position)
r = im.checkoutPNG()
@ -107,12 +136,31 @@ class DPDeliveryCarrier(models.Model):
return result
def dp_get_shipping_price_from_so(self, order):
price = 0
config = self._get_config()
recipient = order.partner_shipping_id if order.partner_shipping_id else order.partner_id
warehouse = order.warehouse_id.partner_id
service = self.sudo().dp_service_type
service_class = self.sudo().dp_service_class
# single-package implementation
weight = self._get_weight(order)
service = self.get_service_by_class(recipient, weight, service_class)
if not service:
raise Warning("Service not available for weight!")
return service.cost_price
# compute the maximum weight of any service within class
#class_max_weight = self.get_class_max_weight(service_class)
# compute number of packages and each weight
#weight, weight_limit, last_package, limits = self.get_package_count(class_max_weight, order)
# iterate over list of packages
#for line in range(1, limits+1):
# if last_package and line == limits:
# weight_limit = last_package
# service = self.get_service_by_class(recipient, weight, service_class)
# price += service.cost_price
#return price
@api.one
def dp_get_tracking_link(self, pickings):
return TRACKING_URL

View File

@ -4,7 +4,18 @@ from openerp import api, fields, models
class SMCShippingDp(models.Model):
_inherit="delivery.carrier"
delivery_type = fields.Selection(selection_add=[('dp','Deutsche Post')])
dp_service_type = fields.Many2one(comodel_name = 'delivery.carrier.dp.service', string = 'DP Service')
dp_service_class = fields.Many2one(comodel_name = 'delivery.carrier.dp.class', string = 'DP Service Class')
# New model for DP Classes (regular mail, registered mail, ...)
class SMCShippingDpClass(models.Model):
_name = "delivery.carrier.dp.class"
name = fields.Char(string="Name", required=1)
# list of services in this class for national delivery
services_natl = fields.Many2many(comodel_name = 'delivery.carrier.dp.service',
relation = 'dp_class_natl_services_rel')
# list of services in this class for international delivery
services_intl = fields.Many2many(comodel_name = 'delivery.carrier.dp.service',
relation = 'dp_class_intl_services_rel')
# New model for DP Products/Services (from ProdWS)
class SMCShippingDpService(models.Model):

View File

@ -11,6 +11,7 @@
</xpath>
</field>
</record>
<record id="shipping_dp_form" model="ir.ui.view">
<field name="name">shipping.dp.form</field>
<field name="model">delivery.carrier</field>
@ -19,12 +20,13 @@
<field name="arch" type="xml">
<xpath expr="//group[@name='Delivery Setting']" col='2' position="after">
<group string="DP Shipping Infomation " attrs="{'invisible':[('delivery_type', '!=', 'dp')]}">
<field name="dp_service_type" attrs="{'required':[('delivery_type', '==', 'dp')]}" />
<field name="dp_service_class" attrs="{'required':[('delivery_type', '==', 'dp')]}" />
</group>
</xpath>
</field>
</record>
<!-- Service Type table derived from ProdWS -->
<record id="delivery_carrier_dp_service_form" model="ir.ui.view">
<field name="name">delivery.carrier.dp.service.form</field>
<field name="model">delivery.carrier.dp.service</field>
@ -69,6 +71,35 @@
</tree>
</field>
</record>
<!-- Service Classes -->
<record id="delivery_carrier_dp_class_form" model="ir.ui.view">
<field name="name">delivery.carrier.dp.class.tree</field>
<field name="model">delivery.carrier.dp.class</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form>
<sheet>
<field name="name"/>
<field name="services_natl"/>
<field name="services_intl"/>
</sheet>
</form>
</field>
</record>
<record id="delivery_carrier_dp_class_tree" model="ir.ui.view">
<field name="name">delivery.carrier.dp.class.tree</field>
<field name="model">delivery.carrier.dp.class</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="package">
<field name="name"/>
<field name="services_natl"/>
<field name="services_intl"/>
</tree>
</field>
</record>
<record id="view_dp_shipping_search" model="ir.ui.view">
<field name="name">stock.picking.dp.shipping.search</field>
<field name="model">stock.picking</field>
@ -86,7 +117,15 @@
<field name="view_mode">tree,form</field>
<field name="view_id" ref="delivery_carrier_dp_service_tree"/>
</record>
<record model="ir.actions.act_window" id="action_delivery_carrier_dp_class">
<field name="name">DP Class List</field>
<field name="res_model">delivery.carrier.dp.class</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="delivery_carrier_dp_class_tree"/>
</record>
<menuitem id="menu_shipping_dp" name="DP Services" parent="delivery.menu_delivery" string="Deutsche Post" />
<menuitem id="menu_shipping_dp_service" parent="menu_shipping_dp" string="Service Type" action="action_delivery_carrier_dp_service"/>
<menuitem id="menu_shipping_dp_class" parent="menu_shipping_dp" string="Service Class" action="action_delivery_carrier_dp_class"/>
</data>
</openerp>