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="code">20</field>
<field name="cost_price">0.70</field> <field name="cost_price">0.70</field>
<field name="weight">0.020</field> <field name="weight">0.020</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_kb" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_kb" model="delivery.carrier.dp.service">
<field name="name">Kompaktbrief</field> <field name="name">Kompaktbrief</field>
@ -15,7 +15,7 @@
<field name="code">11</field> <field name="code">11</field>
<field name="cost_price">0.85</field> <field name="cost_price">0.85</field>
<field name="weight">0.050</field> <field name="weight">0.050</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_gb" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_gb" model="delivery.carrier.dp.service">
<field name="name">Großbrief</field> <field name="name">Großbrief</field>
@ -23,7 +23,7 @@
<field name="code">21</field> <field name="code">21</field>
<field name="cost_price">1.45</field> <field name="cost_price">1.45</field>
<field name="weight">0.500</field> <field name="weight">0.500</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_mb1k" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_mb1k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief</field> <field name="name">Maxibrief</field>
@ -31,7 +31,7 @@
<field name="code">31</field> <field name="code">31</field>
<field name="cost_price">2.60</field> <field name="cost_price">2.60</field>
<field name="weight">1.000</field> <field name="weight">1.000</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_mb2k" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_mb2k" model="delivery.carrier.dp.service">
<field name="name">Maxibrief bis 2000 g + Zusatzentgelt MBf</field> <field name="name">Maxibrief bis 2000 g + Zusatzentgelt MBf</field>
@ -39,17 +39,25 @@
<field name="code">41</field> <field name="code">41</field>
<field name="cost_price">4.80</field> <field name="cost_price">4.80</field>
<field name="weight">2.000</field> <field name="weight">2.000</field>
<field name="international">False</field> <field name="international">0</field>
</record> </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"> <record forcecreate="True" id="dp_service_natl_gb_ein" model="delivery.carrier.dp.service">
<field name="name">Großbrief Integral + EINSCHREIBEN</field> <field name="name">Großbrief Integral + EINSCHREIBEN</field>
<field name="short_name">Gross Natl EIN</field> <field name="short_name">Gross Natl EIN</field>
<field name="code">1027</field> <field name="code">1027</field>
<field name="cost_price">3.95</field> <field name="cost_price">3.95</field>
<field name="weight">0.500</field> <field name="weight">0.500</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_mb1k_ein" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_mb1k_ein" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Integral + EINSCHREIBEN</field> <field name="name">Maxibrief Integral + EINSCHREIBEN</field>
@ -57,15 +65,25 @@
<field name="code">1037</field> <field name="code">1037</field>
<field name="cost_price">5.10</field> <field name="cost_price">5.10</field>
<field name="weight">1.000</field> <field name="weight">1.000</field>
<field name="international">False</field> <field name="international">0</field>
</record> </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"> <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="name">Großbrief Integral + EINSCHREIBEN EINWURF</field>
<field name="short_name">Gross Natl WURF</field> <field name="short_name">Gross Natl WURF</field>
<field name="code">1022</field> <field name="code">1022</field>
<field name="cost_price">3.60</field> <field name="cost_price">3.60</field>
<field name="weight">0.500</field> <field name="weight">0.500</field>
<field name="international">False</field> <field name="international">0</field>
</record> </record>
<record forcecreate="True" id="dp_service_natl_mb1k_wurf" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_natl_mb1k_wurf" model="delivery.carrier.dp.service">
<field name="name">Maxibrief Integral + EINSCHREIBEN EINWURF</field> <field name="name">Maxibrief Integral + EINSCHREIBEN EINWURF</field>
@ -73,17 +91,65 @@
<field name="code">1032</field> <field name="code">1032</field>
<field name="cost_price">4.75</field> <field name="cost_price">4.75</field>
<field name="weight">1.000</field> <field name="weight">1.000</field>
<field name="international">False</field> <field name="international">0</field>
</record> </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"> <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="name">Kompaktbrief Intern. GK Integral + EINSCHREIBEN</field>
<field name="short_name">Kompakt Intl EIN</field> <field name="short_name">Kompakt Intl EIN</field>
<field name="code">11016</field> <field name="code">11016</field>
<field name="cost_price">4.00</field> <field name="cost_price">4.00</field>
<field name="weight">0.050</field> <field name="weight">0.050</field>
<field name="international">True</field> <field name="international">1</field>
</record> </record>
<record forcecreate="True" id="dp_service_intl_gb_ein" model="delivery.carrier.dp.service"> <record forcecreate="True" id="dp_service_intl_gb_ein" model="delivery.carrier.dp.service">
<field name="name">Großbrief Intern. GK Integral + EINSCHREIBEN</field> <field name="name">Großbrief Intern. GK Integral + EINSCHREIBEN</field>
@ -91,7 +157,7 @@
<field name="code">11056</field> <field name="code">11056</field>
<field name="cost_price">6.20</field> <field name="cost_price">6.20</field>
<field name="weight">0.500</field> <field name="weight">0.500</field>
<field name="international">True</field> <field name="international">1</field>
</record> </record>
<record forcecreate="True" id="dp_service_intl_mb1k_ein" model="delivery.carrier.dp.service"> <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> <field name="name">Maxibrief Intern. bis 1.000g GK Integral + EINSCHREIBEN</field>
@ -99,7 +165,7 @@
<field name="code">11076</field> <field name="code">11076</field>
<field name="cost_price">9.50</field> <field name="cost_price">9.50</field>
<field name="weight">1.000</field> <field name="weight">1.000</field>
<field name="international">True</field> <field name="international">1</field>
</record> </record>
<record forcecreate="True" id="dp_service_intl_mb2k_ein" model="delivery.carrier.dp.service"> <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> <field name="name">Maxibrief Intern. bis 2.000g GK Integral + EINSCHREIBEN</field>
@ -107,8 +173,33 @@
<field name="code">11096</field> <field name="code">11096</field>
<field name="cost_price">19.50</field> <field name="cost_price">19.50</field>
<field name="weight">2.000</field> <field name="weight">2.000</field>
<field name="international">True</field> <field name="international">1</field>
</record> </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> </data>
</openerp> </openerp>

View File

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

View File

@ -77,17 +77,46 @@ class DPDeliveryCarrier(models.Model):
last = last, last = last,
address = addr) 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 @api.one
def dp_send_shipping(self, pickings): def dp_send_shipping(self, pickings):
config = self._get_config() config = self._get_config()
order = self.env['sale.order'].search([('name','=',pickings.origin)]) order = self.env['sale.order'].search([('name','=',pickings.origin)])
recipient = pickings.partner_id recipient = pickings.partner_id
warehouse = pickings.picking_type_id.warehouse_id.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 = self.conn_auth_im()
im_recipient = self.build_im_addr(im, recipient) im_recipient = self.build_im_addr(im, recipient)
im_sender = self.build_im_addr(im, warehouse) 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) position = im.build_position(service.code, im_sender, im_recipient)
im.add_position(position) im.add_position(position)
r = im.checkoutPNG() r = im.checkoutPNG()
@ -107,12 +136,31 @@ class DPDeliveryCarrier(models.Model):
return result return result
def dp_get_shipping_price_from_so(self, order): def dp_get_shipping_price_from_so(self, order):
price = 0
config = self._get_config() config = self._get_config()
recipient = order.partner_shipping_id if order.partner_shipping_id else order.partner_id recipient = order.partner_shipping_id if order.partner_shipping_id else order.partner_id
warehouse = order.warehouse_id.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 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 @api.one
def dp_get_tracking_link(self, pickings): def dp_get_tracking_link(self, pickings):
return TRACKING_URL return TRACKING_URL

View File

@ -4,7 +4,18 @@ from openerp import api, fields, models
class SMCShippingDp(models.Model): class SMCShippingDp(models.Model):
_inherit="delivery.carrier" _inherit="delivery.carrier"
delivery_type = fields.Selection(selection_add=[('dp','Deutsche Post')]) 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) # New model for DP Products/Services (from ProdWS)
class SMCShippingDpService(models.Model): class SMCShippingDpService(models.Model):

View File

@ -11,6 +11,7 @@
</xpath> </xpath>
</field> </field>
</record> </record>
<record id="shipping_dp_form" model="ir.ui.view"> <record id="shipping_dp_form" model="ir.ui.view">
<field name="name">shipping.dp.form</field> <field name="name">shipping.dp.form</field>
<field name="model">delivery.carrier</field> <field name="model">delivery.carrier</field>
@ -19,12 +20,13 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='Delivery Setting']" col='2' position="after"> <xpath expr="//group[@name='Delivery Setting']" col='2' position="after">
<group string="DP Shipping Infomation " attrs="{'invisible':[('delivery_type', '!=', 'dp')]}"> <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> </group>
</xpath> </xpath>
</field> </field>
</record> </record>
<!-- Service Type table derived from ProdWS -->
<record id="delivery_carrier_dp_service_form" model="ir.ui.view"> <record id="delivery_carrier_dp_service_form" model="ir.ui.view">
<field name="name">delivery.carrier.dp.service.form</field> <field name="name">delivery.carrier.dp.service.form</field>
<field name="model">delivery.carrier.dp.service</field> <field name="model">delivery.carrier.dp.service</field>
@ -69,6 +71,35 @@
</tree> </tree>
</field> </field>
</record> </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"> <record id="view_dp_shipping_search" model="ir.ui.view">
<field name="name">stock.picking.dp.shipping.search</field> <field name="name">stock.picking.dp.shipping.search</field>
<field name="model">stock.picking</field> <field name="model">stock.picking</field>
@ -86,7 +117,15 @@
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="view_id" ref="delivery_carrier_dp_service_tree"/> <field name="view_id" ref="delivery_carrier_dp_service_tree"/>
</record> </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" 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_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> </data>
</openerp> </openerp>