Comment by [email protected]:
I have created a module that is roughly equivalent, but targeted to Canada
Post (using their electronic services to produce labels and tracking
numbers). I think it would be constructive if I could re-factor it into a
better design with a "plug-in" architecture to handle different delivery
services, so we can make "stock_shipment_package_*" where * = canadapost,
usps, fedex etc. Also allowing "nesting" would be useful too--the module I
wrote just handles the the "outermost box"--not inner boxes or multiple
boxes grouped in pallets.
This is a generalised version of the data model I used:
{{{
shipment = fields.Many2One('stock.shipment.out', 'Shipment',
required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
},
depends=['state'])
pickup_date = fields.Date('Pickup Date', required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
}, depends=['state'])
delivery_method = fields.One2Many( ... )
weight = fields.Numeric('Weight', digits=(3,3), required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
}, depends=['state'])
width = fields.Numeric('Width', digits=(3,1), required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
}, depends=['state'])
length = fields.Numeric('Length', digits=(3,1), required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
}, depends=['state'])
height = fields.Numeric('Height', digits=(3,1), required=True,
states={
'readonly': Not(Equal(Eval('state'), 'draft')),
}, depends=['state'])
}}}
delivery_method would depend on what delivery services have been installed
or configured--in mine it was a fixed list of Canada Post delivery services.
There was a basic workflow with the following states: Draft, Submitted,
Cancelled, Delivered.
Packages would be in "Draft" state until ready for shipment
(and "Submitted") or could be cancelled if the shipment was canceled before
delivery.
Labels were generated and attached as PDF files when the package was put
into Submitted state (the label in my case was generated by Canada Post
Corp (CPC) and returned as a response to a REST call sent by my module).
A "tracking PIN" is generated upon submission too (from the Canada Post
response).
When the mailman comes and picks up the packages they would be put
into "Delivered" state. With the CPC service at least, this is where we
would make another call to Canada Post REST API to "create the manifest"
(that triggers CPC to bill the shipper's account as well as causes CPC to
email the recipient that their order has been accepted for
delivery--without generating a manifest billing is deferred and the
recipient is not notified until the packages are scanned at a sortation
facility).
A "manifest" would be equivalent to a shipment--a group of parcels being
shipped together. I would be fine leaving it like that but it might be
more flexible to have a "manifest" record separate from shipment in case
the physical delivery of a logical shipment somehow differs.
That is what I have so far. Just putting it out there to start discussion
and get the ball rolling.
For more information:
https://code.google.com/p/tryton/wiki/ShipmentPackage