init
authorJulien Moutinho <julm@autogeree.net>
Fri, 25 Oct 2013 11:58:09 +0000 (13:58 +0200)
committerJulien Moutinho <julm@autogeree.net>
Fri, 25 Oct 2013 19:18:25 +0000 (21:18 +0200)
12 files changed:
.gitignore [new file with mode: 0644]
__init__.py [new file with mode: 0644]
__openerp__.py [new file with mode: 0644]
cyclofficine_ivry.py [new file with mode: 0644]
data/base.xml [new file with mode: 0644]
data/members.deb.dependencies [new file with mode: 0644]
data/members.import [new file with mode: 0755]
data/members.xml [new symlink]
data/membership.xml [new file with mode: 0644]
data/partner.xml [new file with mode: 0644]
data/product.xml [new file with mode: 0644]
view/members.xml [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..29f382a
--- /dev/null
@@ -0,0 +1,2 @@
+*.pyc
+sec
diff --git a/__init__.py b/__init__.py
new file mode 100644 (file)
index 0000000..e85a6a4
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import cyclofficine_ivry
diff --git a/__openerp__.py b/__openerp__.py
new file mode 100644 (file)
index 0000000..2332135
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+{
+       'name': 'Cyclofficine Ivry',
+       'version': '2013.10.25',
+       'category': 'Association',
+       'complexity': "normal",
+       'description': """
+Cyclofficine Ivry
+=================
+
+    """,
+       'author': 'Cyclofficine',
+       'website': 'http://cyclocoop.org',
+       'depends': [
+               'bikecoop',
+               'bikecoop_l10n_fr',
+               'remembership',
+        ],
+       'update_xml': [
+               'data/partner.xml',
+               'data/base.xml',
+               'data/product.xml',
+               'data/membership.xml',
+               'data/members.xml',
+               'view/members.xml',
+        ],
+       'installable': True,
+       'auto_install': False,
+       'images': [],
+}
diff --git a/cyclofficine_ivry.py b/cyclofficine_ivry.py
new file mode 100644 (file)
index 0000000..3b20220
--- /dev/null
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+from openerp.osv import osv
+from openerp.osv import fields
+import netsvc
+
+
+class Partner(osv.osv):
+       _inherit = 'res.partner'
+       _order = 'member_ident'
+       _columns = {
+               'member_ident': fields.integer('Member identifier'),
+        }
+
+Partner()
+
+class account_invoice(osv.osv):
+       _inherit = 'account.invoice'
+       def draft2open(self, cr, uid, ids):
+               print ("DEV: [account_invoice] [draft2open]: %s" % str([uid, ids]))
+               wf_service = netsvc.LocalService("workflow")
+               wf_service.trg_validate(uid, 'account.invoice', ids[0], 'invoice_open', cr)
+               return ids
+
+account_invoice()
diff --git a/data/base.xml b/data/base.xml
new file mode 100644 (file)
index 0000000..3d2cd0b
--- /dev/null
@@ -0,0 +1,25 @@
+<openerp>
+       <data>
+               <record id="base.main_partner" model="res.partner">
+                       <field name="category_id" eval="[(6, 0, [ref('res_partner_category_bike_workshop')])]" />
+                       <field name="city">PARIS</field>
+                       <field name="email">ivry@cyclocoop.org</field>
+                       <field name="is_company">True</field>
+                       <field name="name">Cyclofficine d'Ivry</field>
+                       <field name="phone">(+33)</field>
+                       <field name="street">15, rue Pierre Bonnard</field>
+                       <field name="street2"></field>
+                       <field name="type">default</field>
+                       <field name="website">http://cyclocoop.org</field>
+                       <field name="zip">94200</field>
+                       <field search="[('name','=','France')]" model="res.country" name="country_id" />
+                </record>
+               <record id="base.main_company" model="res.company">
+                       <field name="currency_id" ref="base.EUR"/>
+                       <field name="name">Cyclofficine d'Ivry</field>
+                       <field name="partner_id" ref="base.main_partner"/>
+                       <field name="rml_footer"></field>
+                       <field name="rml_header1">Atelier vélo coopératif</field>
+                </record>
+        </data>
+ </openerp>
diff --git a/data/members.deb.dependencies b/data/members.deb.dependencies
new file mode 100644 (file)
index 0000000..d2b2419
--- /dev/null
@@ -0,0 +1,3 @@
+libtext-csv-perl
+libtext-trim-perl
+libxml-generator-perl
diff --git a/data/members.import b/data/members.import
new file mode 100755 (executable)
index 0000000..1037b27
--- /dev/null
@@ -0,0 +1,204 @@
+#!/usr/bin/perl
+
+our $VERSION = '0.0.1';
+use strict;
+use warnings FATAL => qw(all);
+use utf8;
+use open qw/:std :utf8/;
+require Data::Dumper;
+require Encode;
+require IO::Wrap;
+require Text::CSV;
+#require Text::CSV::Encoded;
+require XML::Generator;
+require Text::Trim;
+
+sub parse_date ($) {
+       my ($_) = @_;
+       if ($_) {
+               my ($jj,$mm,undef,$yy) = ($_ =~ m{^\s*([0-3]?[0-9])\s*/\s*([0-1]?[0-9])\s*/\s*(20)?([0-9][0-9])\s*$});
+               return "20$yy-$mm-$jj";
+        }
+       else { return undef };
+ }
+sub parse_euro ($) {
+       my ($_) = @_;
+       if ($_) {
+               my ($num) = ($_ =~ m{^\s*([0-9]+),00\s*€?.$});
+               return $num;
+        }
+       else { return undef };
+ }
+sub parse_line (@) {
+       my ($pass, $xml, $number_next, $adh, $data, $data_noupdate, $data_rejected, $data_reparse) = @_;
+       my ($number, $date_cot1, $cot1, $moyen_cot1, $reduction, $genre, $prenom, $nom, $naissance
+        , $email, $tel_fixe, $tel_mobile, $addr_postale, $cp, $city, $comment) =
+        #map {Text::Trim::trim($_)}
+        @$adh;
+       my $partner = "cyclofficine_ivry";
+       $number = Text::Trim::trim($number);
+       if (not ($number =~ m/^[0-9]+$/)) {
+               if ($pass == 0) {
+                       push @$data_reparse, $adh;
+                       return ($number_next);
+                }
+               else {
+                       $comment
+                        =($comment?"$comment. ":"")
+                        ."(n° malformé d'origine : $number)";
+                       $number = "$number_next";
+                }
+        }
+       if ($number =~ m/^[0-9]+$/) {
+               if ($nom or $email) {
+                       $number      = $number + 0;
+                       $number_next = $number + 1;
+                       $date_cot1 = parse_date($date_cot1);
+                       #$date_cot2 = parse_date($date_cot2);
+                       $cot1      = parse_euro($cot1);
+                       #$cot2      = parse_euro($cot2);
+                       my $city      = ($cp and ($cp =~ m/^750[0-2][0-9]$/) ? "Paris" : undef);
+                       my $country   = ($cp and ($cp =~ m/^UK$/) ? "Royaume-Uni" : "France");
+                       my $phone     = undef;
+                       my $street    = undef;
+                       my %reductions =
+                        ( "Chômeur"          => "unemployed"
+                        , "Chmeur"           => "unemployed"
+                        , "Atelier vélo IdF" => "velorution_idf"
+                        , "Étudiant"         => "student"
+                        , "Etudiant"         => "student"
+                        , "etudiant"         => "student"
+                        , "Retraité"         => "retired"
+                        );
+                       $reduction = Text::Trim::trim($reduction);
+                       $reduction
+                        = exists $reductions{$reduction}
+                        ? $reductions{$reduction}
+                        : "standard";
+                       my %pay_accounts =
+                        ( "Espèces" => "cash"
+                        , "Chèque"  => "bank"
+                        );
+                       my $pay_account_cot1 = Text::Trim::trim($moyen_cot1);
+                       $pay_account_cot1
+                        = exists $pay_accounts{$pay_account_cot1}
+                        ? $pay_accounts{$pay_account_cot1}
+                        : "cash";
+                       push @$data, $xml->record
+                        ( { id    => "res_partner_${partner}_$number"
+                                , model => "res.partner"
+                                }
+                        , $xml->field({name => "name"}, $nom . ($prenom ? " $prenom" : ""))
+                        , $xml->field({name => "member_ident"}, $number)
+                        , $xml->field({name => "type"}, "default")
+                        , ($cp          ? $xml->field({name => "zip"}, $cp) : ())
+                        , ($city        ? $xml->field({name => "city"}, $city) : ())
+                        , ($country     ? $xml->field({name => "country_id", model => "res.country", search => "[('name','=','$country')]"}) : ())
+                        , ($email       ? $xml->field({name => "email"}, $email) : ())
+                        , ($phone       ? $xml->field({name => "phone"}) : ())
+                        , ($addr_postale? $xml->field({name => "street"}, $addr_postale) : ())
+                        , ($comment     ? $xml->field({name => "comment"}, $comment) : ())
+                        );
+                       my %cots =
+                        ( ($cot1 ? ($cot1 => $date_cot1) : ())
+                        #, ($cot2 ? ($cot2 => $date_cot2) : ())
+                        ) ;
+                       while ( my ($amount, $date_from) = each(%cots) ) {
+                               push @$data_noupdate, $xml->function
+                                ( { model => "account.invoice"
+                                        , name  => "pay_and_reconcile"
+                                        }
+                                       , $xml->xmlcmnt('ids')
+                                       , $xml->function
+                                                ( { model => "account.invoice"
+                                                        , name  => "draft2open"
+                                                        }
+                                                , $xml->function
+                                                        ( { model => "res.partner"
+                                                                , name  => "create_membership_invoice"
+                                                                }
+                                                        , $xml->xmlcmnt('partner_id')
+                                                        , $xml->value({eval => "ref('res_partner_${partner}_$number')"})
+                                                        , $xml->xmlcmnt('product_id')
+                                                        , $xml->value({eval => "ref('product_${reduction}_member')"})
+                                                        , $xml->xmlcmnt('context')
+                                                        , $xml->value({eval => "{'amount':$amount, 'date_from':'$date_from'}"})
+                                                        )
+                                                )
+                                       , $xml->xmlcmnt('pay_amount')
+                                       , $xml->value ({eval => "$amount"})
+                                       , $xml->xmlcmnt('pay_account_id')
+                                       , $xml->value ({model => "account.account", search => "[('name', '=', 'Cash')]"})
+                                       , $xml->xmlcmnt("moyen_cot1: $moyen_cot1")
+                                       , $xml->xmlcmnt('period_id')
+                                       , $xml->value ({model => "account.period", search => "[('name', '=', time.strftime('%m/%Y'))]"})
+                                       , $xml->xmlcmnt('pay_journal_id')
+                                       , $xml->value ({model => "account.journal", search => "[('name', '=', 'Cash')]"})
+                                       , $xml->xmlcmnt('writeoff_acc_id')
+                                       , $xml->value ({model => "account.account", search => "[('name', '=', 'Cash')]"})
+                                       , $xml->xmlcmnt('writeoff_period_id')
+                                       , $xml->value ({model => "account.period", search => "[('name', '=', time.strftime('%m/%Y'))]"})
+                                       , $xml->xmlcmnt('writeoff_journal_id')
+                                       , $xml->value ({model => "account.journal", search => "[('name', '=', 'Cash')]"})
+                                       , $xml->xmlcmnt('context')
+                                       , $xml->value ({eval => "{}"})
+                                       , $xml->xmlcmnt('name')
+                                       , $xml->value ({eval => "str('Import de paiement automatique')"})
+                                );
+                        }
+                }
+               else {
+                       push @$data_rejected, $adh;
+                }
+        }
+       return ($number_next);
+ }
+
+sub main () {
+       my $csv = Text::CSV->new
+        ({ binary => 1, eol => $/
+        , sep_char => ';'
+        });
+       my $xml = XML::Generator->new
+        ( escape      => 'always'
+        , conformance => 'strict'
+        , empty       => 'self'
+        , pretty      => 2
+        );
+       my $in = IO::Wrap::wraphandle(\*STDIN);
+       my $csv_head = $csv->getline($in);
+       #print STDERR ("head: ", join("|", @$csv_head), "\n");
+       $csv->column_names(@$csv_head);
+       my $data = [];
+       my $data_noupdate = [];
+       my $data_rejected = [];
+       my $data_reparse = [];
+       my $number_next = 1;
+       while (my $adh = $csv->getline($in)) {
+               #print STDERR ("line: ", join("|", @$adh), "\n");
+               ($number_next) = parse_line(0, $xml, $number_next, $adh, $data, $data_noupdate, $data_rejected, $data_reparse);
+        }
+       foreach (@$data_reparse) {
+               ($number_next) = parse_line(1, $xml, $number_next, $_, $data, $data_noupdate, $data_rejected, []);
+        }
+       push @$data_noupdate, $xml->record
+        ( { id    => "remembership.member_ident_sequence"
+                , model => "ir.sequence"
+                }
+        , $xml->field({name => "number_next"}, $number_next)
+        );
+       binmode STDOUT, ':utf8';
+       print $xml->openerp
+        ( $xml->data(@$data)
+        , $xml->data
+                ( {noupdate=>"1"}
+                , @$data_noupdate )
+        );
+       
+       my $out = IO::Wrap::wraphandle(\*STDERR);
+       foreach (@$data_rejected) {
+               $csv->print($out, $_);
+        }
+ }
+
+main;
diff --git a/data/members.xml b/data/members.xml
new file mode 120000 (symlink)
index 0000000..80cfc17
--- /dev/null
@@ -0,0 +1 @@
+../sec/data/members.xml
\ No newline at end of file
diff --git a/data/membership.xml b/data/membership.xml
new file mode 100644 (file)
index 0000000..e231e1c
--- /dev/null
@@ -0,0 +1,64 @@
+<openerp>
+       <data>
+               <record id="product_standard_member" model="product.product">
+                       <field name="name">Standard member</field>
+                       <field name="list_price">25.00</field>
+                       <field name="standard_price">0.00</field>
+                       <field name="uom_id"    ref="product.product_uom_unit"/>
+                       <field name="uom_po_id" ref="product.product_uom_unit"/>
+                       <field name="type">service</field>
+                       <field name="categ_id" ref="product_category_other"/>
+                       <field name="supply_method">produce</field>
+                       <field name="membership">True</field>
+                       <field name="membership_date2date">True</field>
+                </record>
+               <record id="product_student_member" model="product.product">
+                       <field name="name">Student member</field>
+                       <field name="list_price">15.00</field>
+                       <field name="standard_price">0.00</field>
+                       <field name="uom_id"    ref="product.product_uom_unit"/>
+                       <field name="uom_po_id" ref="product.product_uom_unit"/>
+                       <field name="type">service</field>
+                       <field name="categ_id" ref="product_category_other"/>
+                       <field name="supply_method">produce</field>
+                       <field name="membership">True</field>
+                       <field name="membership_date2date">True</field>
+                </record>
+               <record id="product_unemployed_member" model="product.product">
+                       <field name="name">Unemployed member</field>
+                       <field name="list_price">15.00</field>
+                       <field name="standard_price">0.00</field>
+                       <field name="uom_id"    ref="product.product_uom_unit"/>
+                       <field name="uom_po_id" ref="product.product_uom_unit"/>
+                       <field name="type">service</field>
+                       <field name="categ_id" ref="product_category_other"/>
+                       <field name="supply_method">produce</field>
+                       <field name="membership">True</field>
+                       <field name="membership_date2date">True</field>
+                </record>
+               <record id="product_retired_member" model="product.product">
+                       <field name="name">Retired member</field>
+                       <field name="list_price">15.00</field>
+                       <field name="standard_price">0.00</field>
+                       <field name="uom_id"    ref="product.product_uom_unit"/>
+                       <field name="uom_po_id" ref="product.product_uom_unit"/>
+                       <field name="type">service</field>
+                       <field name="categ_id" ref="product_category_other"/>
+                       <field name="supply_method">produce</field>
+                       <field name="membership">True</field>
+                       <field name="membership_date2date">True</field>
+                </record>
+               <record id="product_velorution_idf_member" model="product.product">
+                       <field name="name">Vélorution ÎdF member</field>
+                       <field name="list_price">15.00</field>
+                       <field name="standard_price">0.00</field>
+                       <field name="uom_id"    ref="product.product_uom_unit"/>
+                       <field name="uom_po_id" ref="product.product_uom_unit"/>
+                       <field name="type">service</field>
+                       <field name="categ_id" ref="product_category_other"/>
+                       <field name="supply_method">produce</field>
+                       <field name="membership">True</field>
+                       <field name="membership_date2date">True</field>
+                </record>
+        </data>
+ </openerp>
diff --git a/data/partner.xml b/data/partner.xml
new file mode 100644 (file)
index 0000000..0ede69d
--- /dev/null
@@ -0,0 +1,21 @@
+<openerp>
+       <data>
+               <record id="res_partner_category_organisation" model="res.partner.category">
+                       <field name="name">Organisation</field>
+                </record>
+               <record id="res_partner_category_company" model="res.partner.category">
+                       <field name="name">Company</field>
+                </record>
+               <record id="res_partner_category_association" model="res.partner.category">
+                       <field name="name">Association</field>
+                       <field name="parent_id" ref="res_partner_category_organisation"/>
+                </record>
+               <record id="res_partner_category_bike_workshop" model="res.partner.category">
+                       <field name="name">Bike workshop</field>
+                       <field name="parent_id" ref="res_partner_category_association"/>
+                </record>
+               <record id="res_partner_category_member" model="res.partner.category">
+                       <field name="name">Member</field>
+                </record>
+        </data>
+ </openerp>
diff --git a/data/product.xml b/data/product.xml
new file mode 100644 (file)
index 0000000..5d36b44
--- /dev/null
@@ -0,0 +1,7 @@
+<openerp>
+       <data>
+               <record id="product_category_other" model="product.category">
+                       <field name="name">Others</field>
+                </record>
+        </data>
+ </openerp>
diff --git a/view/members.xml b/view/members.xml
new file mode 100644 (file)
index 0000000..9ac5a06
--- /dev/null
@@ -0,0 +1,17 @@
+<openerp>
+       <data>
+               <record id="view_bikecoop_members_form" model="ir.ui.view">
+                       <field name="name">res.partner.form</field>
+                       <field name="model">res.partner</field>
+                       <field name="inherit_id" ref="bikecoop.view_bikecoop_members_form"/>
+                       <field name="arch" type="xml">
+                               <xpath expr="//field[@name='gender_id']" position="replace">
+                                       <field name="gender_id" domain="[('domain','=', 'gender')]" placeholder="Other, Female or Male" attrs="{'required':False}"/>
+                                </xpath>
+                               <xpath expr="//field[@name='occupation_id']" position="replace">
+                                       <field name="occupation_id" placeholder="Student/Employee/Other" domain="[('domain','=', 'occupation')]" attrs="{'required':False}"/>
+                                </xpath>
+                        </field>
+                </record>
+        </data>
+ </openerp>