[4suite] Associating payments with charges...

Marc Tompkins marc.tompkins at gmail.com
Mon Jul 28 13:14:37 MDT 2008


On Fri, Jul 25, 2008 at 2:37 PM, Uche Ogbuji <uche at ogbuji.net> wrote:

> > As I write this, an idea just came to me - can I loop over the generic
> > children of a parent element?  I mean, I can't do "for chg in
> > inDoc.stmt.row.charge", but can I do "for child in
> > inDoc.stmt.row(Children)", or some such?  If there is such a beast
> > (I'll check the docs when I get back to my own computer), does it
> > preserve order?  Surely it must...
>
> Yeah, as I was thinking, you have a classic doc order grouping need.
> You'll find the general outline of the idea in the following file:
>
> Amara/demo/bindery/groupby.py
>
> But you'll need something more specific for your need.  Using pushbind
> with simple XPath preceding-sibling checks to find the charge element
> for the present group should be enough.
>
> You definitely don't need SAX for this.
>

Just thought I'd follow up - this turned out to be very simple indeed; the
fact that Bindery preserves the order of xml_children saved my hash.  I
wasn't even aware of "xml_children" until I saw groupby, though.

My input has a structure like so:
<statement>
  <various header info.../>
  <row>
    <charge ... />
    <creditpay .../> # arbitrary number of creditpay and/or creditadj per
charge
    <creditadj .../>
    ... repeat ad nauseam
  </row>
  <various summary info />
</statement>
<statement> .... etc.

My required output looks like this:
<statement>
  <various header info.../>
    <charge ...>
      <payment .../> # adjustment info on same line
      <payment .../> # arbitrary number of payments
      <subtotal .../>  # subtotal for every charge
      <subbalance>26.47</subbalance> # ditto
    </charge>
  <various summary info />
</statement>
<statement> .... etc.

If I were designing the output, I would have made "subtotal" and
"subbalance" attributes of "charge", rather than children... oh well.
(Actually, I've been conditioned not to store derived data, so I probably
wouldn't include them at all.  Hmmm.)

Anyway, my solution ended up being (central loop only, edited for space):

dirtyChg = False
> for e in stmt.row.xml_children:
>     if isinstance(e, unicode):
>         continue
>     if e.nodeName == u"charge":
>         if dirtyChg:  # if a charge record is already open, close it
>             chgElem.xml_append(sbtElem)
>             chgElem.xml_append(sbbElem)
>             outStmt.xml_append(chgElem)
>         dirtyChg = True
>         # create chgElem, sbbElem, sbtElem; save for later
>     elif e.nodeName == u"creditpay": doStuff
>     elif e.nodeName == u"creditadj":  doOtherStuff
> if dirtyChg:  # clean up final charge
>     chgElem.xml_append(sbtElem)
>     chgElem.xml_append(sbbElem)
>     outStmt.xml_append(chgElem)
>

If anyone has a more elegant idea than a "dirty" flag, I'd be glad to hear
it; otherwise I've moved on.  Thanks again for a great toolkit!

-- 
www.fsrtechnologies.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.fourthought.com/pipermail/4suite/attachments/20080728/2a2a4bea/attachment.html>


More information about the 4suite mailing list