From ffdfaa4dc5a7400c4e4afa69de1d7c39981ccdb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Tue, 13 Jan 2015 16:48:08 +0100 Subject: [PATCH 01/26] dmi, set_uom function, translation --- dev/dmi/run1/Kundendaten.ktr | 1737 ++++++++++++++ dev/dmi/run1/Produktdaten.ktr | 2034 +++++++++++++++++ dev/dmi/run1/VAT-Lookup.ktr | 883 +++++++ dev/dmi/run1/Validation.ktr | 1469 ++++++++++++ dev/dmi/run1/cam_dmi/__init__.py | 23 + dev/dmi/run1/cam_dmi/__openerp__.py | 38 + dev/dmi/run1/cam_dmi/res.users.csv | 2 + .../run1/cam_dmi/static/description/icon.png | Bin 0 -> 2870 bytes dev/dmi/run1/input/README.txt | 1 + dev/odoo-server-dev-br.conf | 2 +- dev/odoo-server-dev-sk.conf | 2 +- ext/custom-addons/cam_custom/__openerp__.py | 2 +- ext/custom-addons/cam_custom/i18n/de.po | 25 + setup/lib/config_at.py | 2 +- setup/lib/functions.py | 8 +- 15 files changed, 6223 insertions(+), 5 deletions(-) create mode 100644 dev/dmi/run1/Kundendaten.ktr create mode 100644 dev/dmi/run1/Produktdaten.ktr create mode 100644 dev/dmi/run1/VAT-Lookup.ktr create mode 100644 dev/dmi/run1/Validation.ktr create mode 100755 dev/dmi/run1/cam_dmi/__init__.py create mode 100755 dev/dmi/run1/cam_dmi/__openerp__.py create mode 100644 dev/dmi/run1/cam_dmi/res.users.csv create mode 100644 dev/dmi/run1/cam_dmi/static/description/icon.png create mode 100644 dev/dmi/run1/input/README.txt create mode 100644 ext/custom-addons/cam_custom/i18n/de.po diff --git a/dev/dmi/run1/Kundendaten.ktr b/dev/dmi/run1/Kundendaten.ktr new file mode 100644 index 00000000..d925479b --- /dev/null +++ b/dev/dmi/run1/Kundendaten.ktr @@ -0,0 +1,1737 @@ + + + Kundendaten + + + + Normal + 0 + / + + + + + + + + + +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDTRANSNAMEYTRANSNAMESTATUSYSTATUSLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSSTARTDATEYSTARTDATEENDDATEYENDDATELOGDATEYLOGDATEDEPDATEYDEPDATEREPLAYDATEYREPLAYDATELOG_FIELDYLOG_FIELDEXECUTING_SERVERNEXECUTING_SERVEREXECUTING_USERNEXECUTING_USERCLIENTNCLIENT + + +
+ + +ID_BATCHYID_BATCHSEQ_NRYSEQ_NRLOGDATEYLOGDATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSINPUT_BUFFER_ROWSYINPUT_BUFFER_ROWSOUTPUT_BUFFER_ROWSYOUTPUT_BUFFER_ROWS + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATELOGGING_OBJECT_TYPEYLOGGING_OBJECT_TYPEOBJECT_NAMEYOBJECT_NAMEOBJECT_COPYYOBJECT_COPYREPOSITORY_DIRECTORYYREPOSITORY_DIRECTORYFILENAMEYFILENAMEOBJECT_IDYOBJECT_IDOBJECT_REVISIONYOBJECT_REVISIONPARENT_CHANNEL_IDYPARENT_CHANNEL_IDROOT_CHANNEL_IDYROOT_CHANNEL_ID + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSLOG_FIELDNLOG_FIELD + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATEMETRICS_DATEYMETRICS_DATEMETRICS_CODEYMETRICS_CODEMETRICS_DESCRIPTIONYMETRICS_DESCRIPTIONMETRICS_SUBJECTYMETRICS_SUBJECTMETRICS_TYPEYMETRICS_TYPEMETRICS_VALUEYMETRICS_VALUE + + + +
+ + 0.0 + 0.0 + + 10000 + 50 + 50 + N + Y + 50000 + Y + + N + 1000 + 100 + + + + + + + + + - + 2014/12/19 13:36:06.719 + - + 2015/01/13 16:27:12.108 + + + + + TransformPrioritize streamsY + Prioritize streamsres.partner.csvY + LänderStream lookupY + lieferanten_20150107.csvStream lookupY + kunden_20150107.csvStream lookup 2Y + LänderStream lookup 2Y + Stream lookup 2vat lookupY + vat lookupTransformY + Transform 2Prioritize streamsY + Stream lookupvat lookup 2Y + vat lookup 2Transform 2Y + vat_lookup.csvvat lookupY + vat_lookup.csvvat lookup 2Y + + + Länder + DataGrid + + N + + 1 + + none + + + + + key + String + + + + + -1 + -1 + N + + + value + String + + + + + -1 + -1 + N + + + + Österreichbase.at + Deutschlandbase.de + Italybase.it + Ungarnbase.hu + Belgienbase.be + Schweizbase.ch + + + + 652 + 178 + Y + + + + + Prioritize streams + PrioritizeStreams + + Y + + 1 + + none + + + + + Transform + + + Transform 2 + + + + + 650 + 525 + Y + + + + + Stream lookup + StreamLookup + + Y + + 1 + + none + + + Länder + N + Y + N + N + + + Land + key + + + value + land_xml + + None + + + + + 806 + 217 + Y + + + + + Stream lookup 2 + StreamLookup + + Y + + 1 + + none + + + Länder + N + Y + N + N + + + Land + key + + + value + land_xml + + None + + + + + 539 + 228 + Y + + + + + Transform + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name + + String + + -1 + + -1 + + + + parent_id/id + + String + + -1 + + -1 + + + + street + + String + + -1 + + -1 + + + + city + + String + + -1 + + -1 + + + + zip + + String + + -1 + + -1 + + + + website + + String + + -1 + + -1 + + + + phone + + String + + -1 + + -1 + + + + mobile + + String + + -1 + + -1 + + + + fax + + String + + -1 + + -1 + + + + email + + String + + -1 + + -1 + + + + comment + + String + + -1 + + -1 + + + + ref + + String + + -1 + + -1 + + + + lang + + String + + -1 + + -1 + + + + vat + + String + + -1 + + -1 + + + + date + + String + + -1 + + -1 + + + + is_company + + String + + -1 + + -1 + + + + function + + String + + -1 + + -1 + + + + use_parent_address + + String + + -1 + + -1 + + + + country_id/id + + String + + -1 + + -1 + + + + customer + + String + + -1 + + -1 + + + + supplier + + String + + -1 + + -1 + + + + notify_email + + String + + -1 + + -1 + + + Y + + + 545 + 469 + Y + + + + + Transform 2 + UserDefinedJavaClass + + Y + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name + + String + + -1 + + -1 + + + + parent_id/id + + String + + -1 + + -1 + + + + street + + String + + -1 + + -1 + + + + city + + String + + -1 + + -1 + + + + zip + + String + + -1 + + -1 + + + + website + + String + + -1 + + -1 + + + + phone + + String + + -1 + + -1 + + + + mobile + + String + + -1 + + -1 + + + + fax + + String + + -1 + + -1 + + + + email + + String + + -1 + + -1 + + + + comment + + String + + -1 + + -1 + + + + ref + + String + + -1 + + -1 + + + + lang + + String + + -1 + + -1 + + + + vat + + String + + -1 + + -1 + + + + date + + String + + -1 + + -1 + + + + is_company + + String + + -1 + + -1 + + + + function + + String + + -1 + + -1 + + + + use_parent_address + + String + + -1 + + -1 + + + + country_id/id + + String + + -1 + + -1 + + + + customer + + String + + -1 + + -1 + + + + supplier + + String + + -1 + + -1 + + + + notify_email + + String + + -1 + + -1 + + + Y + + + 817 + 447 + Y + + + + + kunden_20150107.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/input/kunden_20150107.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + Kundennr + String + + + + + -1 + -1 + none + + + Suchname + String + + + + + -1 + -1 + none + + + x + String + + + + + -1 + -1 + none + + + Name + String + + + + + -1 + -1 + none + + + Ansprechpartner + String + + + + + -1 + -1 + none + + + Adresse + String + + + + + -1 + -1 + none + + + PLZ + String + + + + + -1 + -1 + none + + + Ort + String + + + + + -1 + -1 + none + + + Land + String + + + + + -1 + -1 + none + + + Telefon + String + + + + + -1 + -1 + none + + + Fax + String + + + + + -1 + -1 + none + + + mail + String + + + + + -1 + -1 + none + + + Steuernummer + String + + + + + -1 + -1 + none + + + Rechnung per Mail + String + + + + + -1 + -1 + none + + + Zahlungsziel + String + + + + + -1 + -1 + none + + + + + 537 + 115 + Y + +
+ + + lieferanten_20150107.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/input/lieferanten_20150107.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + Lieferanten Nr + String + + + + + -1 + -1 + none + + + Suchname + String + + + + + -1 + -1 + none + + + Bezeichnung + String + + + + + -1 + -1 + none + + + Firmenname + String + + + + + -1 + -1 + none + + + Ansprechpartner + String + + + + + -1 + -1 + none + + + Strasse + String + + + + + -1 + -1 + none + + + PLZ + String + + + + + -1 + -1 + none + + + Stadt + String + + + + + -1 + -1 + none + + + Land + String + + + + + -1 + -1 + none + + + Code + String + + + + + -1 + -1 + none + + + Steuer Nr. + String + + + + + -1 + -1 + none + + + Mail + String + + + + + -1 + -1 + none + + + + + 800 + 115 + Y + +
+ + + res.partner.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + UTF-8 + + N + + Y + + ${GITREPOS}/cam_dmi/res.partner + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name + String + + + + + + none + -1 + -1 + + + parent_id/id + String + + + + + + none + -1 + -1 + + + street + String + + + + + + none + -1 + -1 + + + city + String + + + + + + none + -1 + -1 + + + zip + String + + + + + + none + -1 + -1 + + + website + String + + + + + + none + -1 + -1 + + + phone + String + + + + + + none + -1 + -1 + + + mobile + String + + + + + + none + -1 + -1 + + + fax + String + + + + + + none + -1 + -1 + + + email + String + + + + + + none + -1 + -1 + + + comment + String + + + + + + none + -1 + -1 + + + ref + String + + + + + + none + -1 + -1 + + + lang + String + + + + + + none + -1 + -1 + + + vat + String + + + + + + none + -1 + -1 + + + date + String + + + + + + none + -1 + -1 + + + is_company + String + + + + + + none + -1 + -1 + + + function + String + + + + + + none + -1 + -1 + + + use_parent_address + String + + + + + + none + -1 + -1 + + + country_id/id + String + + + + + + none + -1 + -1 + + + customer + String + + + + + + none + -1 + -1 + + + supplier + String + + + + + + none + -1 + -1 + + + notify_email + String + + + + + + none + -1 + -1 + + + + + 650 + 615 + Y + +
+ + + vat lookup + StreamLookup + + Y + + 1 + + none + + + vat_lookup.csv + N + Y + N + N + + + Steuernummer + vat_old + + + vat_new + help_newvat + + None + + + + + 543 + 336 + Y + + + + + vat lookup 2 + StreamLookup + + Y + + 1 + + none + + + vat_lookup.csv + N + Y + N + N + + + Steuer Nr. + vat_old + + + vat_new + help_newvat + + None + + + + + 810 + 344 + Y + + + + + vat_lookup.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/cam_dmi/vat_lookup.csv + + + N + , + " +
Y
+ 50000 + N + N + N + N + + + + vat_old + String + + + + + -1 + -1 + none + + + vat_new + String + + + + + -1 + -1 + none + + + + + 669 + 257 + Y + +
+ + + + + + N + + diff --git a/dev/dmi/run1/Produktdaten.ktr b/dev/dmi/run1/Produktdaten.ktr new file mode 100644 index 00000000..a4495347 --- /dev/null +++ b/dev/dmi/run1/Produktdaten.ktr @@ -0,0 +1,2034 @@ + + + Produktdaten + + + + Normal + / + + + + + +
+ + + +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDTRANSNAMEYTRANSNAMESTATUSYSTATUSLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSSTARTDATEYSTARTDATEENDDATEYENDDATELOGDATEYLOGDATEDEPDATEYDEPDATEREPLAYDATEYREPLAYDATELOG_FIELDYLOG_FIELDEXECUTING_SERVERNEXECUTING_SERVEREXECUTING_USERNEXECUTING_USERCLIENTNCLIENT + + +
+ + +ID_BATCHYID_BATCHSEQ_NRYSEQ_NRLOGDATEYLOGDATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSINPUT_BUFFER_ROWSYINPUT_BUFFER_ROWSOUTPUT_BUFFER_ROWSYOUTPUT_BUFFER_ROWS + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATELOGGING_OBJECT_TYPEYLOGGING_OBJECT_TYPEOBJECT_NAMEYOBJECT_NAMEOBJECT_COPYYOBJECT_COPYREPOSITORY_DIRECTORYYREPOSITORY_DIRECTORYFILENAMEYFILENAMEOBJECT_IDYOBJECT_IDOBJECT_REVISIONYOBJECT_REVISIONPARENT_CHANNEL_IDYPARENT_CHANNEL_IDROOT_CHANNEL_IDYROOT_CHANNEL_ID + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSLOG_FIELDNLOG_FIELD + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATEMETRICS_DATEYMETRICS_DATEMETRICS_CODEYMETRICS_CODEMETRICS_DESCRIPTIONYMETRICS_DESCRIPTIONMETRICS_SUBJECTYMETRICS_SUBJECTMETRICS_TYPEYMETRICS_TYPEMETRICS_VALUEYMETRICS_VALUE + + + +
+ + 0.0 + 0.0 + + 10000 + 50 + 50 + N + Y + 50000 + Y + + N + 1000 + 100 + + + + + + + + + - + 2014/12/30 09:51:06.375 + - + 2015/01/13 16:27:51.078 + + + + + METransformY + Transformproduct.product.csvY + MengeneinheitenMEY + artikel_20150107.csvSort rowsY + Sort rowsUnique rowsY + Unique rowsTransform 2Y + Transform 2product.category.csvY + artikel_20150107.csvKategorieY + KategorieMEY + Transform 2KategorieY + Transform - Orderpointstock.warehouse.orderpoint.csvY + artikel_20150107.csvTransform - OrderpointY + Lagerstandstock.inventory.line.csvY + MELagerstandY + Inventurauftrag 2stock.inventory.csvY + Lieferanteninfosproduct.supplierinfo.csvY + MELieferanteninfosY + + + Inventurauftrag 2 + DataGrid + + Y + + 1 + + none + + + + + id + String + + + + + -1 + -1 + N + + + name + String + + + + + -1 + -1 + N + + + state + String + + + + + -1 + -1 + N + + + + inv_initinitialbefüllungconfirm + + + + 1228 + 343 + Y + + + + + Kategorie + StreamLookup + + Y + + 1 + + none + + + Transform 2 + N + Y + N + N + + + Artikelgruppe + name + + + id + help_category + + None + + + + + 400 + 365 + Y + + + + + Lagerstand + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + inventory_id/id + + String + + -1 + + -1 + + + + product_id/id + + String + + -1 + + -1 + + + + location_id/id + + String + + -1 + + -1 + + + + product_uom_id/id + + String + + -1 + + -1 + + + + product_qty + + String + + -1 + + -1 + + + Y + + + 1064 + 345 + Y + + + + + Lieferanteninfos + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name/id + + String + + -1 + + -1 + + + + product_name + + String + + -1 + + -1 + + + + product_code + + String + + -1 + + -1 + + + + sequence + + String + + -1 + + -1 + + + + min_qty + + String + + -1 + + -1 + + + + product_tmpl_id/id + + String + + -1 + + -1 + + + + delay + + String + + -1 + + -1 + + + + pricelist_ids/price + + String + + -1 + + -1 + + + + pricelist_ids/min_quantity + + String + + -1 + + -1 + + + Y + + + 1390 + 343 + Y + + + + + ME + StreamLookup + + N + + 1 + + none + + + Mengeneinheiten + N + Y + N + N + + + Einheit + key + + + value + me + + None + + + + + 400 + 481 + Y + + + + + Mengeneinheiten + DataGrid + + Y + + 1 + + none + + + + + key + String + + + + + -1 + -1 + N + + + value + String + + + + + -1 + -1 + N + + + + Ktnproduct.product_uom_unit + Rolproduct.product_uom_unit + Kanproduct.product_uom_unit + lfmproduct.product_uom_meter + Stkproduct.product_uom_unit + qmcam_custom.product_uom_qm + Stgproduct.product_uom_unit + Paarproduct.product_uom_unit + + + + 200 + 255 + Y + + + + + Sort rows + SortRows + + Y + + 1 + + none + + + %%java.io.tmpdir%% + out + 1000000 + + N + + N + + + Artikelgruppe + Y + N + N + + + + + 638 + 151 + Y + + + + + Transform + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name + + String + + -1 + + -1 + + + + default_code + + String + + -1 + + -1 + + + + sale_ok + + String + + -1 + + -1 + + + + type + + String + + -1 + + -1 + + + + uom_id/id + + String + + -1 + + -1 + + + + uom_po_id/id + + String + + -1 + + -1 + + + + route_ids/id + + String + + -1 + + -1 + + + + standard_price + + String + + -1 + + -1 + + + + list_price + + String + + -1 + + -1 + + + + description + + String + + -1 + + -1 + + + + categ_id/id + + String + + -1 + + -1 + + + + purchase_ok + + String + + -1 + + -1 + + + + weight_net + + String + + -1 + + -1 + + + Y + + + 399 + 574 + Y + + + + + Transform - Orderpoint + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name + + String + + -1 + + -1 + + + + product_id/id + + String + + -1 + + -1 + + + + product_min_qty + + String + + -1 + + -1 + + + + product_max_qty + + String + + -1 + + -1 + + + + qty_multiple + + String + + -1 + + -1 + + + Y + + + 825 + 300 + Y + + + + + Transform 2 + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + id + + String + + -1 + + -1 + + + + name + + String + + -1 + + -1 + + + Y + + + 638 + 301 + Y + + + + + Unique rows + Unique + + Y + + 1 + + none + + + N + + N + + Artikelgruppe + N + + + 641 + 213 + Y + + + + + artikel_20150107.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/input/artikel_20150107.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + Artikelnummer + String + + + + + -1 + -1 + none + + + Bezeichnung + String + + + + + -1 + -1 + none + + + Lieferantennummer + String + + + + + -1 + -1 + none + + + Lagerbestand + String + + + + + -1 + -1 + none + + + Mindestbestand + String + + + + + -1 + -1 + none + + + Einheit + String + + + + + -1 + -1 + none + + + MwSt. + String + + + + + -1 + -1 + none + + + Listenpreis ohne MWST + String + + + + + -1 + -1 + none + + + Einkaufspreis ohne MWST + String + + + + + -1 + -1 + none + + + Artikelgruppe + String + + + + + -1 + -1 + none + + + Hersteller + String + + + + + -1 + -1 + none + + + Herstellercode + String + + + + + -1 + -1 + none + + + Lagerwert + String + + + + + -1 + -1 + none + + + + + 638 + 48 + Y + +
+ + + product.category.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/product.category + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name + String + + + + + + none + -1 + -1 + + + + + 644 + 655 + Y + +
+ + + product.product.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/product.product + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name + String + + + + + + none + -1 + -1 + + + default_code + String + + + + + + none + -1 + -1 + + + sale_ok + String + + + + + + none + -1 + -1 + + + type + String + + + + + + none + -1 + -1 + + + uom_id/id + String + + + + + + none + -1 + -1 + + + uom_po_id/id + String + + + + + + none + -1 + -1 + + + route_ids/id + String + + + + + + none + -1 + -1 + + + standard_price + String + + + + + + none + -1 + -1 + + + list_price + String + + + + + + none + -1 + -1 + + + description + String + + + + + + none + -1 + -1 + + + categ_id/id + String + + + + + + none + -1 + -1 + + + purchase_ok + String + + + + + + none + -1 + -1 + + + weight_net + String + + + + + + none + -1 + -1 + + + + + 399 + 651 + Y + +
+ + + product.supplierinfo.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/product.supplierinfo + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name/id + String + + + + + + none + -1 + -1 + + + product_name + String + + + + + + none + -1 + -1 + + + product_code + String + + + + + + none + -1 + -1 + + + sequence + String + + + + + + none + -1 + -1 + + + min_qty + String + + + + + + none + -1 + -1 + + + product_tmpl_id/id + String + + + + + + none + -1 + -1 + + + delay + String + + + + + + none + -1 + -1 + + + pricelist_ids/price + String + + + + + + none + -1 + -1 + + + pricelist_ids/min_quantity + String + + + + + + none + -1 + -1 + + + + + 1399 + 640 + Y + +
+ + + stock.inventory.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/stock.inventory + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name + String + + + + + + none + -1 + -1 + + + state + String + + + + + + none + -1 + -1 + + + + + 1238 + 646 + Y + +
+ + + stock.inventory.line.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/stock.inventory.line + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + inventory_id/id + String + + + + + + none + -1 + -1 + + + product_id/id + String + + + + + + none + -1 + -1 + + + location_id/id + String + + + + + + none + -1 + -1 + + + product_uom_id/id + String + + + + + + none + -1 + -1 + + + product_qty + String + + + + + + none + -1 + -1 + + + + + 1068 + 648 + Y + +
+ + + stock.warehouse.orderpoint.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + + + N + + Y + + ${GITREPOS}/cam_dmi/stock.warehouse.orderpoint + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + id + String + + + + + + none + -1 + -1 + + + name + String + + + + + + none + -1 + -1 + + + product_id/id + String + + + + + + none + -1 + -1 + + + product_min_qty + String + + + + + + none + -1 + -1 + + + product_max_qty + String + + + + + + none + -1 + -1 + + + qty_multiple + String + + + + + + none + -1 + -1 + + + + + 833 + 656 + Y + +
+ + + + + + N + + diff --git a/dev/dmi/run1/VAT-Lookup.ktr b/dev/dmi/run1/VAT-Lookup.ktr new file mode 100644 index 00000000..7db60e48 --- /dev/null +++ b/dev/dmi/run1/VAT-Lookup.ktr @@ -0,0 +1,883 @@ + + + VAT-Lookup + + + + Normal + 0 + / + + + + + +
+ + + +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDTRANSNAMEYTRANSNAMESTATUSYSTATUSLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSSTARTDATEYSTARTDATEENDDATEYENDDATELOGDATEYLOGDATEDEPDATEYDEPDATEREPLAYDATEYREPLAYDATELOG_FIELDYLOG_FIELDEXECUTING_SERVERNEXECUTING_SERVEREXECUTING_USERNEXECUTING_USERCLIENTNCLIENT + + +
+ + +ID_BATCHYID_BATCHSEQ_NRYSEQ_NRLOGDATEYLOGDATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSINPUT_BUFFER_ROWSYINPUT_BUFFER_ROWSOUTPUT_BUFFER_ROWSYOUTPUT_BUFFER_ROWS + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATELOGGING_OBJECT_TYPEYLOGGING_OBJECT_TYPEOBJECT_NAMEYOBJECT_NAMEOBJECT_COPYYOBJECT_COPYREPOSITORY_DIRECTORYYREPOSITORY_DIRECTORYFILENAMEYFILENAMEOBJECT_IDYOBJECT_IDOBJECT_REVISIONYOBJECT_REVISIONPARENT_CHANNEL_IDYPARENT_CHANNEL_IDROOT_CHANNEL_IDYROOT_CHANNEL_ID + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSLOG_FIELDNLOG_FIELD + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATEMETRICS_DATEYMETRICS_DATEMETRICS_CODEYMETRICS_CODEMETRICS_DESCRIPTIONYMETRICS_DESCRIPTIONMETRICS_SUBJECTYMETRICS_SUBJECTMETRICS_TYPEYMETRICS_TYPEMETRICS_VALUEYMETRICS_VALUE + + + +
+ + 0.0 + 0.0 + + 10000 + 50 + 50 + N + Y + 50000 + Y + + N + 1000 + 100 + + + + + + + + + - + 2014/12/30 12:25:19.832 + - + 2015/01/13 16:28:08.336 + + + + + REST ClientGet data from XMLY + kunden_20150107.csvSelect valuesY + ieferanten_20150107.csvSelect values 2Y + Select valuesCreate URLY + Select values 2Create URLY + Create URLREST ClientY + Get data from XMLAufbereitenY + Aufbereitenvat_lookup.csvY + + + Aufbereiten + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + + + + + + vat_old + + String + + -1 + + -1 + + + + vat_new + + String + + -1 + + -1 + + + Y + + + 211 + 467 + Y + + + + + Create URL + UserDefinedJavaClass + + N + + 1 + + none + + + + + + TRANSFORM_CLASS + + Processor + + / + String url = "http://vatid.eu/check/"; + String country = vat.substring(0,2); + String vat_nr = vat.substring(2,vat.length()); + + get(Fields.Out, "help_url").setValue(out, url + "/" + country + "/" + vat_nr); + get(Fields.Out, "vat_old").setValue(out, get(Fields.In, "vat").getString(r)); + // Send the row on to the next step. + putRow(data.outputRowMeta, out); + } + + return true; +}]]> + + + + + help_url + + String + + -1 + + -1 + + + + vat_old + + String + + -1 + + -1 + + + Y + + + 214 + 219 + Y + + + + + Get data from XML + getXMLData + + Y + + 1 + + none + + + N + + N + N + N + N + N + N + N + N + Y + + UTF-8 + + + + + N + N + + + + valid + /response/valid + node + valueof + None + + + + + -1 + -1 + none + N + + + vatnr + /response/vat-number + node + valueof + None + + + + + -1 + -1 + none + N + + + country_code + /response/country-code + node + valueof + None + + + + + -1 + -1 + none + N + + + 0 + /response/valid + Y + N + help_result + + + + + + + + + + + + 213 + 380 + Y + + + + + REST Client + Rest + + N + + 1 + + none + + + TEXT PLAIN + GET + + Y + N + + help_url + + + Encrypted + + + N + + Encrypted + + + + + + help_result + help_resultcode + + + + + 212 + 287 + Y + + + + + Select values + SelectValues + + Y + + 1 + + none + + + Steuernummer + vat + -2 + -2 + N + + + 124 + 159 + Y + + + + + Select values 2 + SelectValues + + Y + + 1 + + none + + + Steuer Nr. + vat + -2 + -2 + N + + + 290 + 155 + Y + + + + + ieferanten_20150107.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/input/lieferanten_20150107.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + Lieferanten Nr + String + + + + + -1 + -1 + none + + + Suchname + String + + + + + -1 + -1 + none + + + Bezeichnung + String + + + + + -1 + -1 + none + + + Firmenname + String + + + + + -1 + -1 + none + + + Ansprechpartner + String + + + + + -1 + -1 + none + + + Strasse + String + + + + + -1 + -1 + none + + + PLZ + String + + + + + -1 + -1 + none + + + Stadt + String + + + + + -1 + -1 + none + + + Land + String + + + + + -1 + -1 + none + + + Code + String + + + + + -1 + -1 + none + + + Steuer Nr. + String + + + + + -1 + -1 + none + + + Mail + String + + + + + -1 + -1 + none + + + + + 282 + 68 + Y + +
+ + + kunden_20150107.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/input/kunden_20150107.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + Kundennr + String + + + + + -1 + -1 + none + + + Suchname + String + + + + + -1 + -1 + none + + + Type + String + + + + + -1 + -1 + none + + + Name + String + + + + + -1 + -1 + none + + + Ansprechpartner + String + + + + + -1 + -1 + none + + + Adresse + String + + + + + -1 + -1 + none + + + PLZ + String + + + + + -1 + -1 + none + + + Ort + String + + + + + -1 + -1 + none + + + Land + String + + + + + -1 + -1 + none + + + Telefon + String + + + + + -1 + -1 + none + + + Fax + String + + + + + -1 + -1 + none + + + mail + String + + + + + -1 + -1 + none + + + Steuernummer + String + + + + + -1 + -1 + none + + + Rechnung per Mail + String + + + + + -1 + -1 + none + + + Zahlungsziel + String + + + + + -1 + -1 + none + + + + + 127 + 69 + Y + +
+ + + vat_lookup.csv + TextFileOutput + + Y + + 1 + + none + + + , + " + N + N +
Y
+
N
+ DOS + None + UTF-8 + + N + + Y + + ${GITREPOS}/cam_dmi/vat_lookup + N + N + N + csv + N + N + N + N + N + N + + Y + N + N + 0 + + + + vat_old + String + + + + + + none + -1 + -1 + + + vat_new + String + + + + + + none + -1 + -1 + + + + + 208 + 587 + Y + +
+ + + + + + N + + diff --git a/dev/dmi/run1/Validation.ktr b/dev/dmi/run1/Validation.ktr new file mode 100644 index 00000000..3e647d2a --- /dev/null +++ b/dev/dmi/run1/Validation.ktr @@ -0,0 +1,1469 @@ + + + Validation + + + + Normal + / + + + + + +
+ + + +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDTRANSNAMEYTRANSNAMESTATUSYSTATUSLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSSTARTDATEYSTARTDATEENDDATEYENDDATELOGDATEYLOGDATEDEPDATEYDEPDATEREPLAYDATEYREPLAYDATELOG_FIELDYLOG_FIELDEXECUTING_SERVERNEXECUTING_SERVEREXECUTING_USERNEXECUTING_USERCLIENTNCLIENT + + +
+ + +ID_BATCHYID_BATCHSEQ_NRYSEQ_NRLOGDATEYLOGDATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSINPUT_BUFFER_ROWSYINPUT_BUFFER_ROWSOUTPUT_BUFFER_ROWSYOUTPUT_BUFFER_ROWS + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATELOGGING_OBJECT_TYPEYLOGGING_OBJECT_TYPEOBJECT_NAMEYOBJECT_NAMEOBJECT_COPYYOBJECT_COPYREPOSITORY_DIRECTORYYREPOSITORY_DIRECTORYFILENAMEYFILENAMEOBJECT_IDYOBJECT_IDOBJECT_REVISIONYOBJECT_REVISIONPARENT_CHANNEL_IDYPARENT_CHANNEL_IDROOT_CHANNEL_IDYROOT_CHANNEL_ID + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATETRANSNAMEYTRANSNAMESTEPNAMEYSTEPNAMESTEP_COPYYSTEP_COPYLINES_READYLINES_READLINES_WRITTENYLINES_WRITTENLINES_UPDATEDYLINES_UPDATEDLINES_INPUTYLINES_INPUTLINES_OUTPUTYLINES_OUTPUTLINES_REJECTEDYLINES_REJECTEDERRORSYERRORSLOG_FIELDNLOG_FIELD + + +
+ +ID_BATCHYID_BATCHCHANNEL_IDYCHANNEL_IDLOG_DATEYLOG_DATEMETRICS_DATEYMETRICS_DATEMETRICS_CODEYMETRICS_CODEMETRICS_DESCRIPTIONYMETRICS_DESCRIPTIONMETRICS_SUBJECTYMETRICS_SUBJECTMETRICS_TYPEYMETRICS_TYPEMETRICS_VALUEYMETRICS_VALUE + + + +
+ + 0.0 + 0.0 + + 10000 + 50 + 50 + N + Y + 50000 + Y + + N + 1000 + 100 + + + + + + + + + - + 2014/12/30 14:48:36.101 + - + 2015/01/13 16:28:48.168 + + + + + product.template.csvData ValidatorY + res.partner.csvData Validator 2Y + stock.warehouse.orderpoint.csvData Validator 3Y + stock.inventory.line.csvData Validator 3 2Y + vat_lookup.csvData Validator 2Y + product.product.csvData Validator 2 2N + product.template.csvData Validator 2 2N + product.product.csvData Validator 3 2Y + product.product.csvData Validator 3Y + product.supplierinfo.csvData Validator 3 2 2Y + product.product.csvData Validator 3 2 2Y + res.partner.csvData Validator 3 2 2Y + + + Data Validator + Validator + + Y + + 1 + + none + + +N +N +| + uom_id/id +uom_id + + +N +N +N +None +N + + + + + + + + + + + + + +N + + + + uom_po_id/id +uom_po_id + + +N +N +N +None +N + + + + + + + + + + + + + +N + + + + categ_id/id +category_id + + +N +N +N +None +N + + + + + + + + + + + + + +N + + + + name +name + + +N +N +N +None +N + + + + + + + + + + + + + +N + + + + default_code +default_code + + +Y +N +N +None +N + + + + + + + + + + + + + +N + + + + + + 510 + 532 + Y + + + + + Data Validator 2 + Validator + + Y + + 1 + + none + + +N +N +| + name +name + + +N +N +N +None +N + + + + + + + + + + + + + +N + + + + vat +vat exists + + +Y +N +N +None +N + + + + + + + + + + + + + +Y +vat_lookup.csv +vat_new + + + + 356 + 509 + Y + + + + + Data Validator 2 2 + Validator + + Y + + 1 + + none + + +N +N +| + product_tmpl_id/id +product_tmpl_id + + +N +N +N +None +N + + + + + + + + + + + + + +Y +product.template.csv +id + + + + 174 + 514 + Y + + + + + Data Validator 3 + Validator + + Y + + 1 + + none + + +N +N +| + product_id/id +product_id + + +N +N +N +None +N + + + + + + + + + + + + + +Y +product.product.csv +id + + + + 710 + 529 + Y + + + + + Data Validator 3 2 + Validator + + Y + + 1 + + none + + +N +N +| + product_id/id +product_id + + +N +N +N +None +N + + + + + + + + + + + + + +Y +product.product.csv +id + + + + 901 + 541 + Y + + + + + Data Validator 3 2 2 + Validator + + Y + + 1 + + none + + +N +N +| + product_tmpl_id/id +product_id + + +N +N +N +None +N + + + + + + + + + + + + + +Y +product.product.csv +id + + name/id +Lieferant partner_id + + +N +N +N +None +N + + + + + + + + + + + + + +Y +res.partner.csv +id + + + + 1124 + 535 + Y + + + + + product.product.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/cam_dmi/product.product.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + product_tmpl_id/id + String + + + + + -1 + -1 + none + + + + + 93 + 136 + Y + +
+ + + product.supplierinfo.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/cam_dmi/product.supplierinfo.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + name/id + String + + + + + -1 + -1 + none + + + product_name + String + + + + + -1 + -1 + none + + + product_code + String + + + + + -1 + -1 + none + + + sequence + String + + + + + -1 + -1 + none + + + min_qty + String + + + + + -1 + -1 + none + + + product_tmpl_id/id + String + + + + + -1 + -1 + none + + + delay + String + + + + + -1 + -1 + none + + + pricelist_ids/price + String + + + + + -1 + -1 + none + + + pricelist_ids/min_quantity + String + + + + + -1 + -1 + none + + + + + 1200 + 135 + Y + +
+ + + product.template.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/cam_dmi/product.template.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + name + String + + + + + -1 + -1 + none + + + default_code + String + + + + + -1 + -1 + none + + + sale_ok + String + + + + + -1 + -1 + none + + + type + String + + + + + -1 + -1 + none + + + uom_id/id + String + + + + + -1 + -1 + none + + + uom_po_id/id + String + + + + + -1 + -1 + none + + + route_ids/id + String + + + + + -1 + -1 + none + + + standard_price + String + + + + + -1 + -1 + none + + + list_price + String + + + + + -1 + -1 + none + + + description + String + + + + + -1 + -1 + none + + + categ_id/id + String + + + + + -1 + -1 + none + + + purchase_ok + String + + + + + -1 + -1 + none + + + weight_net + String + + + + + -1 + -1 + none + + + + + 541 + 133 + Y + +
+ + + res.partner.csv + CsvInput + + N + + 1 + + none + + + ${GITREPOS}/cam_dmi/res.partner.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + name + String + + + + + -1 + -1 + none + + + parent_id/id + String + + + + + -1 + -1 + none + + + street + String + + + + + -1 + -1 + none + + + city + String + + + + + -1 + -1 + none + + + zip + String + + + + + -1 + -1 + none + + + website + String + + + + + -1 + -1 + none + + + phone + String + + + + + -1 + -1 + none + + + mobile + String + + + + + -1 + -1 + none + + + fax + String + + + + + -1 + -1 + none + + + email + String + + + + + -1 + -1 + none + + + comment + String + + + + + -1 + -1 + none + + + ref + String + + + + + -1 + -1 + none + + + lang + String + + + + + -1 + -1 + none + + + vat + String + + + + + -1 + -1 + none + + + date + String + + + + + -1 + -1 + none + + + is_company + String + + + + + -1 + -1 + none + + + function + String + + + + + -1 + -1 + none + + + use_parent_address + String + + + + + -1 + -1 + none + + + country_id/id + String + + + + + -1 + -1 + none + + + customer + String + + + + + -1 + -1 + none + + + supplier + String + + + + + -1 + -1 + none + + + notify_email + String + + + + + -1 + -1 + none + + + + + 380 + 129 + Y + +
+ + + stock.inventory.line.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/cam_dmi/stock.inventory.line.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + inventory_id/id + String + + + + + -1 + -1 + none + + + product_id/id + String + + + + + -1 + -1 + none + + + location_id/id + String + + + + + -1 + -1 + none + + + product_uom_id/id + String + + + + + -1 + -1 + none + + + product_qty + String + + + + + -1 + -1 + none + + + + + 1000 + 133 + Y + +
+ + + stock.warehouse.orderpoint.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/cam_dmi/stock.warehouse.orderpoint.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + id + String + + + + + -1 + -1 + none + + + name + String + + + + + -1 + -1 + none + + + product_id/id + String + + + + + -1 + -1 + none + + + product_min_qty + String + + + + + -1 + -1 + none + + + product_max_qty + String + + + + + -1 + -1 + none + + + qty_multiple + String + + + + + -1 + -1 + none + + + + + 764 + 134 + Y + +
+ + + vat_lookup.csv + CsvInput + + Y + + 1 + + none + + + ${GITREPOS}/cam_dmi/vat_lookup.csv + + + N + , + " +
Y
+ 50000 + Y + N + N + N + + + + vat_old + String + + + + + -1 + -1 + none + + + vat_new + String + + + + + -1 + -1 + none + + + + + 243 + 132 + Y + +
+ + + + + + N + + diff --git a/dev/dmi/run1/cam_dmi/__init__.py b/dev/dmi/run1/cam_dmi/__init__.py new file mode 100755 index 00000000..49a09e55 --- /dev/null +++ b/dev/dmi/run1/cam_dmi/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/dev/dmi/run1/cam_dmi/__openerp__.py b/dev/dmi/run1/cam_dmi/__openerp__.py new file mode 100755 index 00000000..e642b311 --- /dev/null +++ b/dev/dmi/run1/cam_dmi/__openerp__.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +{ + 'name': 'Datenübernahme', + 'category': 'Custom', + 'version': '1.0', + 'description': """Datenübernahme""", + 'author': 'camadeus GmbH', + 'website': 'http://www.camadeus.at', + 'depends': ['mail','cam_reports'], + 'data': [ + 'res.users.csv', + ], + 'installable': True, + 'auto_install': False, +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/dev/dmi/run1/cam_dmi/res.users.csv b/dev/dmi/run1/cam_dmi/res.users.csv new file mode 100644 index 00000000..ad16983a --- /dev/null +++ b/dev/dmi/run1/cam_dmi/res.users.csv @@ -0,0 +1,2 @@ +"id","name","login","password","email","groups_id/id","tz","mobile","phone","function" +"p_xxx","Max Mustermann","mustermann@max.at","x","mustermann@max.at","base.group_sale_salesman_all_leads,account.group_account_invoice,base.group_erp_manager,stock.group_stock_user,purchase.group_purchase_user","Europe/Vienna",,, diff --git a/dev/dmi/run1/cam_dmi/static/description/icon.png b/dev/dmi/run1/cam_dmi/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7ee3b90ede569d07369b51f5036c9c0de4e9b2 GIT binary patch literal 2870 zcma);XE+-Q8-}B$h*9cO(W+W8YHu|osHhRtII2;j?V%bgv4WyawMr>zjo4~b6^+KO zy-LNX+F~ST?OlX?&iVKK`>ywTp7(j5>w5p+(Uum*9Kb6;006*Y0yDHe+m`=`<-(cA zac`HLEe4deF%(eRE3kZaTyQltHU!ZBne6&P+*!lw19LzD0Bk(}hyj342c4D7XcKcI zW-<`Sp$PPl67mE9fR!eO`Zhu1Yh%GazvlUywloDOO)Yim{s0j;a?#54`AdvV-hL1F$(fA01)q<;M!IO%tp|u$GvJx2X^o z{e$_6>Uy12iCX}UM;Tn_!q-B9f=&!Di11?=YpE7i0{aIN@a9|6r)mA&i}5GnGjAmA zw?8N;oOBeYJ2jyH^V+O%bLbv+WF!W)E!MJl71JBjo>IMoB*ISnuY#+*p-Y-9k#tlt zN3)hh97P~ReMf1eUC&eQt{3C+%+vHZJHvgC=G-KFm`vkWq48V}shZ26XbA!3QzC{ar}NWJJhF{igFlv7-q zf4m)BjX(%7Dy8PlIj{6HuQk$-#WEd}YdU>FjRe8^-6wO$=g~t>jCi$lVW<#-`9n3f zWvDNEp08hVUip=?LYls4xnx4#oR1drA$6d|r6o{K^xN(P03Gh4<^{jlz^^P78mfw5 zdqm-2kKmfAbp|<)fp~diLoigXT=5c>{aFKppr8J%h~Pb+0EStuja%ZEf->8Do417; z0_8>09&Qa4_d|uT9?$xW>E7$t6NEKE7w&4rUIx0nHPcrMek>OwdQvy5ahXI4g)`3{f$S(I%G@1pfg z)0k2}E1D~io212z-rs+0VnUQm zy*C}pWzHodbU(Ft%(9$CQ+xV1cdS~RhWz5cemoUld+XXXk;pjJmqU-JGYFsqsKVo)?DwZ_)op)|L)g1n@r%~EAz{rOPPApX#SOmoO20b&BvCv4EOE0@;x$ks7mU;&W$TkIR;WOYrwy2btFLyeSOrCKp%-t^oLp(U0m^@$C*{7T}B@oIqV z#;WkO7@RsGMY}am6zL|+qF0}^t(DY&#e4?X3>wK-2w!XY(5g*ma$j>Q#`$_+0`bKKfRHs;;Mj&PL;*W*EtQca3ZS zr^@AKAVv!@(Q@?}FXW$)0FP%C!irRcHuKu{wK0L}JThehQyy67AAE~BFQ7rz6o$h) zpNeV@LWp}D&LM(!t)4X0?VF|3FFhv&!u(`Wr^Kj_$iY;zTz=gGIhqnuk0#hso=^}e z7~Sug|FS!Darg}p9Y9^WB9V!C-Ju%ZsvK7RQ}l#_GHdYUU+ZEl?dQ^}RDKKdIhtYE zKRGeM7Uaywx~wws{S<_YAV68ka2FCZQ;3k2P$Qgbpj-nO)#$2bW}$2K@*{Q*jFby zrX$i8?lZin&Y{|m@K*83En;;!+7g3lLvc688W-fz`H8Tmub-cAn+luppv>O7$?F_9Zu44tSoitvJqrgZGlRnLom-s9DUHdeV`}OR!MeC)a%+;7mpBwLo<9P8=MKZAS%|7|oWyn+c6V31EINKDtsoNn$z)P2zw)cX zK>=-_h%R2<(Ilg%PJ$-`lEJeIb$C2T&qYK(%f!lx`>e{bWNCEi|2bs=_m3!%-(H2>n5T$7cRT_qoL##|;hnL1V}_&-*)wY5!0Shp1HtvHlFU@f+%zc+Zvi6Z-t42)LC zl$Y;(EGfxf{3Yc|0Br@)1~sR-Sr}hEa8z;QT4g#6mQ|> zp%@deeoHy*!=^x|@PDqHhX~CS=H`kVYd~CFgx|k^|JmVdRI2jdN&%~XReDdy^(|gs zUr<$~Opx|{YAwVPV^(U>Xtbq+18Y-P5-vT&i=WyVPk$HRH3rt+ZN;dS=uC(Y1>#Qw zFY+Lf`pV|O8^s{y94th?xe;-$GwvF7bGB9HuP+hqD&4&qTB+*Zf|bZSHa2bRWRh9t zJre_i^I$O8#@3dAoKU-Qqq~dr#%HF9f%a7I@bJ*a#>R*C$Ct7N8X8(0oSf|0T^{ss z4|-2Ip<;Y``Uy|h>7Y$AY`FaC9gPnKty z;Rb~FUuXIVJ, 2012. +# + +msgid "" +msgstr "" +"Project-Id-Version: camadeus\n" +"Report-Msgid-Bugs-To: Andreas Brueckl \n" +"POT-Creation-Date: 2014-09-23 16:26+0000\n" +"PO-Revision-Date: 2014-08-14 16:14+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Abkhazian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2014-09-24 09:44+0000\n" +"X-Generator: Launchpad (build 17196)\n" + +#. module: cam_custom +#: field:product.product,default_code:0 +#: field:product.template,default_code:0 +msgid "Internal Reference" +msgstr "Artikelnummer" diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index e46f6261..c38baa22 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -93,7 +93,7 @@ class Config(): # }, # 'account.invoice': { # 'number_next_actual': 2000, -# 'prefix': '14-', +# 'prefix': '15-', # 'padding': 4, # }, } diff --git a/setup/lib/functions.py b/setup/lib/functions.py index df8984d8..13977342 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -285,7 +285,13 @@ class CamadeusFunctions(): for uom_xml_id in active_uoms: uom_id = self._execute('ir.model.data', 'xmlid_to_res_id', uom_xml_id) active_ids.append(uom_id) - + + # Set all UOMs to active + ids = self._execute('product.uom', 'search', ['|',('active','=',True),('active','=',False)]) + res = self._execute('product.uom', 'write', ids, {'active': True}) + if not res: + return False + # Set all other UOMs to inactive inactive_ids = self._execute('product.uom', 'search', [('id','not in',active_ids)]) res = self._execute('product.uom', 'write', inactive_ids, {'active': False}) From 5c5e245f7475bd689c705ed4ff87354fd306d91d Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Tue, 20 Jan 2015 15:50:29 +0100 Subject: [PATCH 02/26] Added module web_printscreen_zb --- .../web_printscreen_zb/__init__.py | 27 + .../web_printscreen_zb/__openerp__.py | 41 + .../web_printscreen_zb/controllers.py | 185 +++ .../static/src/js/web_printscreen_export.js | 122 ++ .../static/src/xml/web_printscreen_export.xml | 16 + .../web_printscreen_zb/trml2pdf.py | 1044 +++++++++++++++++ .../views/web_printscreen_zb.xml | 12 + setup/lib/config_at.py | 3 +- 8 files changed, 1449 insertions(+), 1 deletion(-) create mode 100644 ext/custom-addons/web_printscreen_zb/__init__.py create mode 100644 ext/custom-addons/web_printscreen_zb/__openerp__.py create mode 100644 ext/custom-addons/web_printscreen_zb/controllers.py create mode 100644 ext/custom-addons/web_printscreen_zb/static/src/js/web_printscreen_export.js create mode 100644 ext/custom-addons/web_printscreen_zb/static/src/xml/web_printscreen_export.xml create mode 100644 ext/custom-addons/web_printscreen_zb/trml2pdf.py create mode 100644 ext/custom-addons/web_printscreen_zb/views/web_printscreen_zb.xml diff --git a/ext/custom-addons/web_printscreen_zb/__init__.py b/ext/custom-addons/web_printscreen_zb/__init__.py new file mode 100644 index 00000000..63149b13 --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/__init__.py @@ -0,0 +1,27 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd. +# (http://wwww.zbeanztech.com) +# contact@zbeanztech.com +# prajul@zbeanztech.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +import trml2pdf +import controllers + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/ext/custom-addons/web_printscreen_zb/__openerp__.py b/ext/custom-addons/web_printscreen_zb/__openerp__.py new file mode 100644 index 00000000..b074cd8e --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/__openerp__.py @@ -0,0 +1,41 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd. +# (http://wwww.zbeanztech.com) +# contact@zbeanztech.com +# prajul@zbeanztech.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'Web Printscreen ZB', + 'version': '1.0', + 'category': 'Web', + 'description': """ + Module to export current active tree view in to excel report + """, + 'author': 'Zesty Beanz Technologies', + 'website': 'http://www.zbeanztech.com', + 'depends': ['web'], + 'data': ['views/web_printscreen_zb.xml'], + 'qweb': ['static/src/xml/web_printscreen_export.xml'], + 'installable': True, + 'auto_install': False, + 'web_preload': False, +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/ext/custom-addons/web_printscreen_zb/controllers.py b/ext/custom-addons/web_printscreen_zb/controllers.py new file mode 100644 index 00000000..8c383af8 --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/controllers.py @@ -0,0 +1,185 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd. +# (http://wwww.zbeanztech.com) +# contact@zbeanztech.com +# prajul@zbeanztech.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +try: + import json +except ImportError: + import simplejson as json +import openerp.addons.web.http as openerpweb +from openerp.addons.web.controllers.main import ExcelExport +from openerp.addons.web.controllers.main import Export +import re +from cStringIO import StringIO +from lxml import etree +import trml2pdf +import time, os +import locale +import openerp.tools as tools +try: + import xlwt +except ImportError: + xlwt = None + +class ZbExcelExport(ExcelExport): + _cp_path = '/web/export/zb_excel_export' + + def from_data(self, fields, rows): + workbook = xlwt.Workbook() + worksheet = workbook.add_sheet('Sheet 1') + style = xlwt.easyxf('align: wrap yes') + font = xlwt.Font() + font.bold = True + style.font = font + ignore_index = [] + count = 0 + for i, fieldname in enumerate(fields): + if fieldname.get('header_data_id', False): + field_name = fieldname.get('header_name', '') + worksheet.write(0, i-count, field_name, style) + worksheet.col(i).width = 8000 + else: + count += 1 + ignore_index.append(i) + style = xlwt.easyxf('align: wrap yes') + bold_style = xlwt.easyxf('align: wrap yes') + font = xlwt.Font() + font.bold = True + bold_style.font = font + for row_index, row in enumerate(rows): + count = 0 + for cell_index, cell_value in enumerate(row): + if cell_index not in ignore_index: + cell_style = style + if cell_value.get('bold', False): + cell_style = bold_style + cellvalue = cell_value.get('data', '') + if isinstance(cellvalue, basestring): + cellvalue = re.sub("\r", " ", cellvalue) + if cell_value.get('number', False) and cellvalue: + cellvalue = float(cellvalue) + if cellvalue is False: cellvalue = None + worksheet.write(row_index + 1, cell_index - count, cellvalue, cell_style) + else: + count += 1 + fp = StringIO() + workbook.save(fp) + fp.seek(0) + data = fp.read() + fp.close() + return data + + @openerpweb.httprequest + def index(self, req, data, token): + data = json.loads(data) + return req.make_response( + self.from_data(data.get('headers', []), data.get('rows', [])), + headers=[ + ('Content-Disposition', 'attachment; filename="%s"' + % data.get('model', 'Export.xls')), + ('Content-Type', self.content_type) + ], + cookies={'fileToken': token} + ) + +class ExportPdf(Export): + _cp_path = '/web/export/zb_pdf' + fmt = { + 'tag': 'pdf', + 'label': 'PDF', + 'error': None + } + + @property + def content_type(self): + return 'application/pdf' + + def filename(self, base): + return base + '.pdf' + + def from_data(self, uid, fields, rows, company_name): + pageSize=[210.0,297.0] + new_doc = etree.Element("report") + config = etree.SubElement(new_doc, 'config') + def _append_node(name, text): + n = etree.SubElement(config, name) + n.text = text + _append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')))) + _append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize)) + _append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,)) + _append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,)) + _append_node('PageFormat', 'a4') + _append_node('header-date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')))) + _append_node('company', company_name) + l = [] + t = 0 + temp = [] + tsum = [] + skip_index = [] + header = etree.SubElement(new_doc, 'header') + i = 0 + for f in fields: + if f.get('header_data_id', False): + value = f.get('header_name', "") + field = etree.SubElement(header, 'field') + field.text = tools.ustr(value) + else: + skip_index.append(i) + i += 1 + lines = etree.SubElement(new_doc, 'lines') + for row_lines in rows: + node_line = etree.SubElement(lines, 'row') + j = 0 + for row in row_lines: + if not j in skip_index: + para = "yes" + tree = "no" + value = row.get('data', '') + if row.get('bold', False): + para = "group" + if row.get('number', False): + tree = "float" + col = etree.SubElement(node_line, 'col', para=para, tree=tree) + col.text = tools.ustr(value) + j += 1 + transform = etree.XSLT( + etree.parse(os.path.join(tools.config['root_path'], + 'addons/base/report/custom_new.xsl'))) + rml = etree.tostring(transform(new_doc)) + self.obj = trml2pdf.parseNode(rml, title='Printscreen') + return self.obj + +class ZbPdfExport(ExportPdf): + _cp_path = '/web/export/zb_pdf_export' + + @openerpweb.httprequest + def index(self, req, data, token): + data = json.loads(data) + uid = data.get('uid', False) + return req.make_response(self.from_data(uid, data.get('headers', []), data.get('rows', []), + data.get('company_name','')), + headers=[('Content-Disposition', + 'attachment; filename=PDF Export'), + ('Content-Type', self.content_type)]) +# cookies={'fileToken': long(token)}) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/ext/custom-addons/web_printscreen_zb/static/src/js/web_printscreen_export.js b/ext/custom-addons/web_printscreen_zb/static/src/js/web_printscreen_export.js new file mode 100644 index 00000000..dfcbe0a2 --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/static/src/js/web_printscreen_export.js @@ -0,0 +1,122 @@ +openerp.web_printscreen_zb = function(instance, m) { + + var _t = instance.web._t; + var QWeb = instance.web.qweb; + + instance.web.ListView.include({ + load_list: function () { + var self = this; + this._super.apply(this, arguments); + self.$pager.find(".oe_list_button_import_excel").unbind('click').click(function(event){self.export_to_excel("excel")}) + self.$pager.find(".oe_list_button_import_pdf").unbind('click').click(function(event){self.export_to_excel("pdf")}) + }, + export_to_excel: function(export_type) { + var self = this + var export_type = export_type + view = this.getParent() + // Find Header Element + header_eles = self.$el.find('.oe_list_header_columns') + header_name_list = [] + $.each(header_eles,function(){ + $header_ele = $(this) + header_td_elements = $header_ele.find('th') + $.each(header_td_elements,function(){ + $header_td = $(this) + text = $header_td.text().trim() || "" + data_id = $header_td.attr('data-id') + if (text && !data_id){ + data_id = 'group_name' + } + header_name_list.push({'header_name': text.trim(), 'header_data_id': data_id}) + // } + }); + }); + + //Find Data Element + data_eles = self.$el.find('.oe_list_content > tbody > tr') + export_data = [] + $.each(data_eles,function(){ + data = [] + $data_ele = $(this) + is_analysis = false + if ($data_ele.text().trim()){ + //Find group name + group_th_eles = $data_ele.find('th') + $.each(group_th_eles,function(){ + $group_th_ele = $(this) + text = $group_th_ele.text().trim() || "" + is_analysis = true + data.push({'data': text, 'bold': true}) + }); + data_td_eles = $data_ele.find('td') + $.each(data_td_eles,function(){ + $data_td_ele = $(this) + text = $data_td_ele.text().trim() || "" + if ($data_td_ele && $data_td_ele[0].classList.contains('oe_number') && !$data_td_ele[0].classList.contains('oe_list_field_float_time')){ + text = text.replace('%', '') + text = instance.web.parse_value(text, { type:"float" }) + data.push({'data': text || "", 'number': true}) + } + else{ + data.push({'data': text}) + } + }); + export_data.push(data) + } + }); + + //Find Footer Element + + footer_eles = self.$el.find('.oe_list_content > tfoot> tr') + $.each(footer_eles,function(){ + data = [] + $footer_ele = $(this) + footer_td_eles = $footer_ele.find('td') + $.each(footer_td_eles,function(){ + $footer_td_ele = $(this) + text = $footer_td_ele.text().trim() || "" + if ($footer_td_ele && $footer_td_ele[0].classList.contains('oe_number')){ + text = instance.web.parse_value(text, { type:"float" }) + data.push({'data': text || "", 'bold': true, 'number': true}) + } + else{ + data.push({'data': text, 'bold': true}) + } + }); + export_data.push(data) + }); + + //Export to excel + $.blockUI(); + if (export_type === 'excel'){ + view.session.get_file({ + url: '/web/export/zb_excel_export', + data: {data: JSON.stringify({ + model : view.model, + headers : header_name_list, + rows : export_data, + })}, + complete: $.unblockUI + }); + } + else{ + console.log(view) + new instance.web.Model("res.users").get_func("read")(this.session.uid, ["company_id"]).then(function(res) { + new instance.web.Model("res.company").get_func("read")(res['company_id'][0], ["name"]).then(function(result) { + view.session.get_file({ + url: '/web/export/zb_pdf_export', + data: {data: JSON.stringify({ + uid: view.session.uid, + model : view.model, + headers : header_name_list, + rows : export_data, + company_name: result['name'] + })}, + complete: $.unblockUI + }); + }); + }); + } + }, + }); +}; diff --git a/ext/custom-addons/web_printscreen_zb/static/src/xml/web_printscreen_export.xml b/ext/custom-addons/web_printscreen_zb/static/src/xml/web_printscreen_export.xml new file mode 100644 index 00000000..7af23f9e --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/static/src/xml/web_printscreen_export.xml @@ -0,0 +1,16 @@ + + + + + PDF + + Excel + + + diff --git a/ext/custom-addons/web_printscreen_zb/trml2pdf.py b/ext/custom-addons/web_printscreen_zb/trml2pdf.py new file mode 100644 index 00000000..5a29c331 --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/trml2pdf.py @@ -0,0 +1,1044 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd. +# (http://wwww.zbeanztech.com) +# contact@zbeanztech.com +# prajul@zbeanztech.com +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + + +import sys +import copy +import reportlab +import re +from reportlab.pdfgen import canvas +from reportlab import platypus +from openerp.report.render.rml2pdf import utils +from openerp.report.render.rml2pdf import color +import os +import logging +from lxml import etree +import base64 +from reportlab.platypus.doctemplate import ActionFlowable +from openerp.tools.safe_eval import safe_eval as eval +from reportlab.lib.units import inch,cm,mm +from openerp.tools.misc import file_open +from reportlab.pdfbase import pdfmetrics +from reportlab.lib.pagesizes import A4, letter + +try: + from cStringIO import StringIO + _hush_pyflakes = [ StringIO ] +except ImportError: + from StringIO import StringIO + +_logger = logging.getLogger(__name__) + +encoding = 'utf-8' + +def _open_image(filename, path=None): + """Attempt to open a binary file and return the descriptor + """ + if os.path.isfile(filename): + return open(filename, 'rb') + for p in (path or []): + if p and os.path.isabs(p): + fullpath = os.path.join(p, filename) + if os.path.isfile(fullpath): + return open(fullpath, 'rb') + try: + if p: + fullpath = os.path.join(p, filename) + else: + fullpath = filename + return file_open(fullpath) + except IOError: + pass + raise IOError("File %s cannot be found in image path" % filename) + +class NumberedCanvas(canvas.Canvas): + def __init__(self, *args, **kwargs): + canvas.Canvas.__init__(self, *args, **kwargs) + self._codes = [] + self._flag=False + self._pageCount=0 + self._currentPage =0 + self._pageCounter=0 + self.pages={} + + def showPage(self): + self._currentPage +=1 + if not self._flag: + self._pageCount += 1 + else: + self.pages.update({self._currentPage:self._pageCount}) + self._codes.append({'code': self._code, 'stack': self._codeStack}) + self._startPage() + self._flag=False + + def pageCount(self): + if self.pages.get(self._pageCounter,False): + self._pageNumber=0 + self._pageCounter +=1 + key=self._pageCounter + if not self.pages.get(key,False): + while not self.pages.get(key,False): + key += 1 + self.setFont("Helvetica", 8) + self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), + " %(this)i / %(total)i" % { + 'this': self._pageNumber+1, + 'total': self.pages.get(key,False), + } + ) + + def save(self): + """add page info to each page (page x of y)""" + # reset page counter + self._pageNumber = 0 + for code in self._codes: + self._code = code['code'] + self._codeStack = code['stack'] + self.pageCount() + canvas.Canvas.showPage(self) +# self.restoreState() + self._doc.SaveToFile(self._filename, self) + +class PageCount(platypus.Flowable): + def __init__(self, story_count=0): + platypus.Flowable.__init__(self) + self.story_count = story_count + + def draw(self): + self.canv.beginForm("pageCount%d" % self.story_count) + self.canv.setFont("Helvetica", utils.unit_get(str(8))) + self.canv.drawString(0, 0, str(self.canv.getPageNumber())) + self.canv.endForm() + +class PageReset(platypus.Flowable): + def draw(self): + self.canv._doPageReset = True +class PageReset(platypus.Flowable): + def draw(self): + self.canv._doPageReset = True + +class _rml_styles(object,): + def __init__(self, nodes, localcontext): + self.localcontext = localcontext + self.styles = {} + self.styles_obj = {} + self.names = {} + self.table_styles = {} + self.default_style = reportlab.lib.styles.getSampleStyleSheet() + + for node in nodes: + for style in node.findall('blockTableStyle'): + self.table_styles[style.get('id')] = self._table_style_get(style) + for style in node.findall('paraStyle'): + sname = style.get('name') + self.styles[sname] = self._para_style_update(style) + + self.styles_obj[sname] = reportlab.lib.styles.ParagraphStyle(sname, self.default_style["Normal"], **self.styles[sname]) + + for variable in node.findall('initialize'): + for name in variable.findall('name'): + self.names[ name.get('id')] = name.get('value') + + def _para_style_update(self, node): + data = {} + for attr in ['textColor', 'backColor', 'bulletColor', 'borderColor']: + if node.get(attr): + data[attr] = color.get(node.get(attr)) + for attr in ['fontName', 'bulletFontName', 'bulletText']: + if node.get(attr): + data[attr] = node.get(attr) + for attr in ['fontSize', 'leftIndent', 'rightIndent', 'spaceBefore', 'spaceAfter', + 'firstLineIndent', 'bulletIndent', 'bulletFontSize', 'leading', + 'borderWidth','borderPadding','borderRadius']: + if node.get(attr): + data[attr] = utils.unit_get(node.get(attr)) + if node.get('alignment'): + align = { + 'right':reportlab.lib.enums.TA_RIGHT, + 'center':reportlab.lib.enums.TA_CENTER, + 'justify':reportlab.lib.enums.TA_JUSTIFY + } + data['alignment'] = align.get(node.get('alignment').lower(), reportlab.lib.enums.TA_LEFT) + return data + + def _table_style_get(self, style_node): + styles = [] + for node in style_node: + start = utils.tuple_int_get(node, 'start', (0,0) ) + stop = utils.tuple_int_get(node, 'stop', (-1,-1) ) + if node.tag=='blockValign': + styles.append(('VALIGN', start, stop, str(node.get('value')))) + elif node.tag=='blockFont': + styles.append(('FONT', start, stop, str(node.get('name')))) + elif node.tag=='blockTextColor': + styles.append(('TEXTCOLOR', start, stop, color.get(str(node.get('colorName'))))) + elif node.tag=='blockLeading': + styles.append(('LEADING', start, stop, utils.unit_get(node.get('length')))) + elif node.tag=='blockAlignment': + styles.append(('ALIGNMENT', start, stop, str(node.get('value')))) + elif node.tag=='blockSpan': + styles.append(('SPAN', start, stop)) + elif node.tag=='blockLeftPadding': + styles.append(('LEFTPADDING', start, stop, utils.unit_get(node.get('length')))) + elif node.tag=='blockRightPadding': + styles.append(('RIGHTPADDING', start, stop, utils.unit_get(node.get('length')))) + elif node.tag=='blockTopPadding': + styles.append(('TOPPADDING', start, stop, utils.unit_get(node.get('length')))) + elif node.tag=='blockBottomPadding': + styles.append(('BOTTOMPADDING', start, stop, utils.unit_get(node.get('length')))) + elif node.tag=='blockBackground': + styles.append(('BACKGROUND', start, stop, color.get(node.get('colorName')))) + if node.get('size'): + styles.append(('FONTSIZE', start, stop, utils.unit_get(node.get('size')))) + elif node.tag=='lineStyle': + kind = node.get('kind') + kind_list = [ 'GRID', 'BOX', 'OUTLINE', 'INNERGRID', 'LINEBELOW', 'LINEABOVE','LINEBEFORE', 'LINEAFTER' ] + assert kind in kind_list + thick = 1 + if node.get('thickness'): + thick = float(node.get('thickness')) + styles.append((kind, start, stop, thick, color.get(node.get('colorName')))) + return platypus.tables.TableStyle(styles) + + def para_style_get(self, node): + style = False + sname = node.get('style') + if sname: + if sname in self.styles_obj: + style = self.styles_obj[sname] + else: + _logger.warning('Warning: style not found, %s - setting default!\n' % (node.get('style'),) ) + if not style: + style = self.default_style['Normal'] + para_update = self._para_style_update(node) + if para_update: + # update style only is necessary + style = copy.deepcopy(style) + style.__dict__.update(para_update) + return style + +class _rml_doc(object): + def __init__(self, node, localcontext=None, images=None, path='.', title=None): + if images is None: + images = {} + if localcontext is None: + localcontext = {} + self.localcontext = localcontext + self.etree = node + self.filename = self.etree.get('filename') + self.images = images + self.path = path + self.title = title + + def docinit(self, els): + from reportlab.lib.fonts import addMapping + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + + for node in els: + for font in node.findall('registerFont'): + name = font.get('fontName').encode('ascii') + fname = font.get('fontFile').encode('ascii') + if name not in pdfmetrics._fonts: + pdfmetrics.registerFont(TTFont(name, fname)) + addMapping(name, 0, 0, name) #normal + addMapping(name, 0, 1, name) #italic + addMapping(name, 1, 0, name) #bold + addMapping(name, 1, 1, name) #italic and bold + + def setTTFontMapping(self,face, fontname, filename, mode='all'): + from reportlab.lib.fonts import addMapping + from reportlab.pdfbase import pdfmetrics + from reportlab.pdfbase.ttfonts import TTFont + + if fontname not in pdfmetrics._fonts: + pdfmetrics.registerFont(TTFont(fontname, filename)) + if mode == 'all': + addMapping(face, 0, 0, fontname) #normal + addMapping(face, 0, 1, fontname) #italic + addMapping(face, 1, 0, fontname) #bold + addMapping(face, 1, 1, fontname) #italic and bold + elif (mode== 'normal') or (mode == 'regular'): + addMapping(face, 0, 0, fontname) #normal + elif mode == 'italic': + addMapping(face, 0, 1, fontname) #italic + elif mode == 'bold': + addMapping(face, 1, 0, fontname) #bold + elif mode == 'bolditalic': + addMapping(face, 1, 1, fontname) #italic and bold + + def _textual_image(self, node): + rc = '' + for n in node: + rc +=( etree.tostring(n) or '') + n.tail + return base64.decodestring(node.tostring()) + + def _images(self, el): + result = {} + for node in el.findall('.//image'): + rc =( node.text or '') + result[node.get('name')] = base64.decodestring(rc) + return result + + def render(self, out): + el = self.etree.findall('.//docinit') + if el: + self.docinit(el) + + el = self.etree.findall('.//stylesheet') + self.styles = _rml_styles(el,self.localcontext) + + el = self.etree.findall('.//images') + if el: + self.images.update( self._images(el[0]) ) + + el = self.etree.findall('.//template') + if len(el): + pt_obj = _rml_template(self.localcontext, out, el[0], self, images=self.images, path=self.path, title=self.title) + el = utils._child_get(self.etree, self, 'story') + pt_obj.render(el) + else: + self.canvas = canvas.Canvas(out) + pd = self.etree.find('pageDrawing')[0] + pd_obj = _rml_canvas(self.canvas, self.localcontext, None, self, self.images, path=self.path, title=self.title) + pd_obj.render(pd) + + self.canvas.showPage() + self.canvas.save() + +class _rml_canvas(object): + def __init__(self, canvas, localcontext, doc_tmpl=None, doc=None, images=None, path='.', title=None): + if images is None: + images = {} + self.localcontext = localcontext + self.canvas = canvas + self.styles = doc.styles + self.doc_tmpl = doc_tmpl + self.doc = doc + self.images = images + self.path = path + self.title = title + if self.title: + self.canvas.setTitle(self.title) + + def _textual(self, node, x=0, y=0): + text = node.text and node.text.encode('utf-8') or '' + rc = utils._process_text(self, text) + for n in node: + if n.tag == 'seq': + from reportlab.lib.sequencer import getSequencer + seq = getSequencer() + rc += str(seq.next(n.get('id'))) + if n.tag == 'pageCount': + if x or y: + self.canvas.translate(x,y) + self.canvas.doForm('pageCount%s' % (self.canvas._storyCount,)) + if x or y: + self.canvas.translate(-x,-y) + if n.tag == 'pageNumber': + rc += str(self.canvas.getPageNumber()) + rc += utils._process_text(self, n.tail) + return rc.replace('\n','') + + def _drawString(self, node): + v = utils.attr_get(node, ['x','y']) + text=self._textual(node, **v) + text = utils.xml2str(text) + self.canvas.drawString(text=text, **v) + + def _drawCenteredString(self, node): + v = utils.attr_get(node, ['x','y']) + text=self._textual(node, **v) + text = utils.xml2str(text) + self.canvas.drawCentredString(text=text, **v) + + def _drawRightString(self, node): + v = utils.attr_get(node, ['x','y']) + text=self._textual(node, **v) + text = utils.xml2str(text) + self.canvas.drawRightString(text=text, **v) + + def _rect(self, node): + if node.get('round'): + self.canvas.roundRect(radius=utils.unit_get(node.get('round')), **utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'})) + else: + self.canvas.rect(**utils.attr_get(node, ['x','y','width','height'], {'fill':'bool','stroke':'bool'})) + + def _ellipse(self, node): + x1 = utils.unit_get(node.get('x')) + x2 = utils.unit_get(node.get('width')) + y1 = utils.unit_get(node.get('y')) + y2 = utils.unit_get(node.get('height')) + + self.canvas.ellipse(x1,y1,x2,y2, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'})) + + def _curves(self, node): + line_str = node.text.split() + lines = [] + while len(line_str)>7: + self.canvas.bezier(*[utils.unit_get(l) for l in line_str[0:8]]) + line_str = line_str[8:] + + def _lines(self, node): + line_str = node.text.split() + lines = [] + while len(line_str)>3: + lines.append([utils.unit_get(l) for l in line_str[0:4]]) + line_str = line_str[4:] + self.canvas.lines(lines) + + def _grid(self, node): + xlist = [utils.unit_get(s) for s in node.get('xs').split(',')] + ylist = [utils.unit_get(s) for s in node.get('ys').split(',')] + + self.canvas.grid(xlist, ylist) + + def _translate(self, node): + dx = utils.unit_get(node.get('dx')) or 0 + dy = utils.unit_get(node.get('dy')) or 0 + self.canvas.translate(dx,dy) + + def _circle(self, node): + self.canvas.circle(x_cen=utils.unit_get(node.get('x')), y_cen=utils.unit_get(node.get('y')), r=utils.unit_get(node.get('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'})) + + def _place(self, node): + flows = _rml_flowable(self.doc, self.localcontext, images=self.images, path=self.path, title=self.title).render(node) + infos = utils.attr_get(node, ['x','y','width','height']) + + infos['y']+=infos['height'] + for flow in flows: + w,h = flow.wrap(infos['width'], infos['height']) + if w<=infos['width'] and h<=infos['height']: + infos['y']-=h + flow.drawOn(self.canvas,infos['x'],infos['y']) + infos['height']-=h + else: + raise ValueError("Not enough space") + + def _line_mode(self, node): + ljoin = {'round':1, 'mitered':0, 'bevelled':2} + lcap = {'default':0, 'round':1, 'square':2} + + if node.get('width'): + self.canvas.setLineWidth(utils.unit_get(node.get('width'))) + if node.get('join'): + self.canvas.setLineJoin(ljoin[node.get('join')]) + if node.get('cap'): + self.canvas.setLineCap(lcap[node.get('cap')]) + if node.get('miterLimit'): + self.canvas.setDash(utils.unit_get(node.get('miterLimit'))) + if node.get('dash'): + dashes = node.get('dash').split(',') + for x in range(len(dashes)): + dashes[x]=utils.unit_get(dashes[x]) + self.canvas.setDash(node.get('dash').split(',')) + + def _image(self, node): + import urllib + import urlparse + from reportlab.lib.utils import ImageReader + nfile = node.get('file') + if not nfile: + if node.get('name'): + image_data = self.images[node.get('name')] + _logger.debug("Image %s used", node.get('name')) + s = StringIO(image_data) + else: + newtext = node.text + if self.localcontext: + res = utils._regex.findall(newtext) + for key in res: + newtext = eval(key, {}, self.localcontext) or '' + image_data = None + if newtext: + image_data = base64.decodestring(newtext) + if image_data: + s = StringIO(image_data) + else: + _logger.debug("No image data!") + return False + else: + if nfile in self.images: + s = StringIO(self.images[nfile]) + else: + try: + up = urlparse.urlparse(str(nfile)) + except ValueError: + up = False + if up and up.scheme: + # RFC: do we really want to open external URLs? + # Are we safe from cross-site scripting or attacks? + _logger.debug("Retrieve image from %s", nfile) + u = urllib.urlopen(str(nfile)) + s = StringIO(u.read()) + else: + _logger.debug("Open image file %s ", nfile) + s = _open_image(nfile, path=self.path) + try: + img = ImageReader(s) + (sx,sy) = img.getSize() + _logger.debug("Image is %dx%d", sx, sy) + args = { 'x': 0.0, 'y': 0.0, 'mask': 'auto'} + for tag in ('width','height','x','y'): + if node.get(tag): + args[tag] = utils.unit_get(node.get(tag)) + if ('width' in args) and (not 'height' in args): + args['height'] = sy * args['width'] / sx + elif ('height' in args) and (not 'width' in args): + args['width'] = sx * args['height'] / sy + elif ('width' in args) and ('height' in args): + if (float(args['width'])/args['height'])>(float(sx)>sy): + args['width'] = sx * args['height'] / sy + else: + args['height'] = sy * args['width'] / sx + self.canvas.drawImage(img, **args) + finally: + s.close() +# self.canvas._doc.SaveToFile(self.canvas._filename, self.canvas) + + def _path(self, node): + self.path = self.canvas.beginPath() + self.path.moveTo(**utils.attr_get(node, ['x','y'])) + for n in utils._child_get(node, self): + if not n.text : + if n.tag=='moveto': + vals = utils.text_get(n).split() + self.path.moveTo(utils.unit_get(vals[0]), utils.unit_get(vals[1])) + elif n.tag=='curvesto': + vals = utils.text_get(n).split() + while len(vals)>5: + pos=[] + while len(pos)<6: + pos.append(utils.unit_get(vals.pop(0))) + self.path.curveTo(*pos) + elif n.text: + data = n.text.split() # Not sure if I must merge all TEXT_NODE ? + while len(data)>1: + x = utils.unit_get(data.pop(0)) + y = utils.unit_get(data.pop(0)) + self.path.lineTo(x,y) + if (not node.get('close')) or utils.bool_get(node.get('close')): + self.path.close() + self.canvas.drawPath(self.path, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'})) + + def setFont(self, node): + fontname = node.get('name') + if fontname not in pdfmetrics.getRegisteredFontNames()\ + or fontname not in pdfmetrics.standardFonts: + # let reportlab attempt to find it + try: + pdfmetrics.getFont(fontname) + except Exception: + _logger.debug('Could not locate font %s, substituting default: %s', + fontname, + self.canvas._fontname) + fontname = self.canvas._fontname + return self.canvas.setFont(fontname, utils.unit_get(node.get('size'))) + + def render(self, node): + tags = { + 'drawCentredString': self._drawCenteredString, + 'drawRightString': self._drawRightString, + 'drawString': self._drawString, + 'rect': self._rect, + 'ellipse': self._ellipse, + 'lines': self._lines, + 'grid': self._grid, + 'curves': self._curves, + 'fill': lambda node: self.canvas.setFillColor(color.get(node.get('color'))), + 'stroke': lambda node: self.canvas.setStrokeColor(color.get(node.get('color'))), + 'setFont': self.setFont , + 'place': self._place, + 'circle': self._circle, + 'lineMode': self._line_mode, + 'path': self._path, + 'rotate': lambda node: self.canvas.rotate(float(node.get('degrees'))), + 'translate': self._translate, + 'image': self._image + } + for n in utils._child_get(node, self): + if n.tag in tags: + tags[n.tag](n) + +class _rml_draw(object): + def __init__(self, localcontext, node, styles, images=None, path='.', title=None): + if images is None: + images = {} + self.localcontext = localcontext + self.node = node + self.styles = styles + self.canvas = None + self.images = images + self.path = path + self.canvas_title = title + + def render(self, canvas, doc): + canvas.saveState() + cnv = _rml_canvas(canvas, self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title) + cnv.render(self.node) + canvas.restoreState() + +class _rml_Illustration(platypus.flowables.Flowable): + def __init__(self, node, localcontext, styles, self2): + self.localcontext = (localcontext or {}).copy() + self.node = node + self.styles = styles + self.width = utils.unit_get(node.get('width')) + self.height = utils.unit_get(node.get('height')) + self.self2 = self2 + def wrap(self, *args): + return self.width, self.height + def draw(self): + drw = _rml_draw(self.localcontext ,self.node,self.styles, images=self.self2.images, path=self.self2.path, title=self.self2.title) + drw.render(self.canv, None) + +class _rml_flowable(object): + def __init__(self, doc, localcontext, images=None, path='.', title=None): + if images is None: + images = {} + self.localcontext = localcontext + self.doc = doc + self.styles = doc.styles + self.images = images + self.path = path + self.title = title + + def _textual(self, node): + rc1 = utils._process_text(self, node.text or '') + for n in utils._child_get(node,self): + txt_n = copy.deepcopy(n) + for key in txt_n.attrib.keys(): + if key in ('rml_except', 'rml_loop', 'rml_tag'): + del txt_n.attrib[key] + if not n.tag == 'bullet': + txt_n.text = utils.xml2str(self._textual(n)) + txt_n.tail = n.tail and utils.xml2str(utils._process_text(self, n.tail.replace('\n',''))) or '' + rc1 += etree.tostring(txt_n) + return rc1 + + def _table(self, node): + children = utils._child_get(node,self,'tr') + if not children: + return None + length = 0 + colwidths = None + rowheights = None + data = [] + styles = [] + posy = 0 + for tr in children: + paraStyle = None + if tr.get('style'): + st = copy.deepcopy(self.styles.table_styles[tr.get('style')]) + for si in range(len(st._cmds)): + s = list(st._cmds[si]) + s[1] = (s[1][0],posy) + s[2] = (s[2][0],posy) + st._cmds[si] = tuple(s) + styles.append(st) + if tr.get('paraStyle'): + paraStyle = self.styles.styles[tr.get('paraStyle')] + data2 = [] + posx = 0 + for td in utils._child_get(tr, self,'td'): + if td.get('style'): + st = copy.deepcopy(self.styles.table_styles[td.get('style')]) + for s in st._cmds: + s[1][1] = posy + s[2][1] = posy + s[1][0] = posx + s[2][0] = posx + styles.append(st) + if td.get('paraStyle'): + # TODO: merge styles + paraStyle = self.styles.styles[td.get('paraStyle')] + posx += 1 + + flow = [] + for n in utils._child_get(td, self): + if n.tag == etree.Comment: + n.text = '' + continue + fl = self._flowable(n, extra_style=paraStyle) + if isinstance(fl,list): + flow += fl + else: + flow.append( fl ) + + if not len(flow): + flow = self._textual(td) + data2.append( flow ) + if len(data2)>length: + length=len(data2) + for ab in data: + while len(ab) tag: + # - we reset page number to 0 + # - we add an new PageCount flowable (relative to the current + # story number), but not for NumeredCanvas at is handle page + # count itself) + # NOTE: _rml_template render() method add a PageReset flowable at end + # of each story, so we're sure to pass here at least once per story. + if not isinstance(self.canv, NumberedCanvas): + self.handle_flowable([ PageCount(story_count=self.canv._storyCount) ]) + self.canv._pageCount = self.page + self.page = 0 + self.canv._flag = True + self.canv._pageNumber = 0 + self.canv._doPageReset = False + self.canv._storyCount += 1 + +class _rml_template(object): + def __init__(self, localcontext, out, node, doc, images=None, path='.', title=None): + if images is None: + images = {} + if not localcontext: + localcontext={'internal_header':True} + self.localcontext = localcontext + self.images= images + self.path = path + self.title = title + + pagesize_map = {'a4': A4, + 'us_letter': letter + } + pageSize = (841.8897637795275, 595.275590551181) + self.doc_tmpl = TinyDocTemplate(out, pagesize=pageSize, **utils.attr_get(node, ['leftMargin','rightMargin','topMargin','bottomMargin'], {'allowSplitting':'int','showBoundary':'bool','rotation':'int','title':'str','author':'str'})) + self.page_templates = [] + self.styles = doc.styles + self.doc = doc + self.image=[] + pts = node.findall('pageTemplate') + for pt in pts: + frames = [] + for frame_el in pt.findall('frame'): + frame = platypus.Frame( **(utils.attr_get(frame_el, ['x1','y1', 'width','height', 'leftPadding', 'rightPadding', 'bottomPadding', 'topPadding'], {'id':'str', 'showBoundary':'bool'})) ) + if utils.attr_get(frame_el, ['last']): + frame.lastFrame = True + frames.append( frame ) + try : + gr = pt.findall('pageGraphics')\ + or pt[1].findall('pageGraphics') + except Exception: # FIXME: be even more specific, perhaps? + gr='' + if len(gr): +# self.image=[ n for n in utils._child_get(gr[0], self) if n.tag=='image' or not self.localcontext] + drw = _rml_draw(self.localcontext,gr[0], self.doc, images=images, path=self.path, title=self.title) + self.page_templates.append( platypus.PageTemplate(frames=frames, onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) + else: + drw = _rml_draw(self.localcontext,node,self.doc,title=self.title) + self.page_templates.append( platypus.PageTemplate(frames=frames,onPage=drw.render, **utils.attr_get(pt, [], {'id':'str'}) )) + self.doc_tmpl.addPageTemplates(self.page_templates) + + def render(self, node_stories): + if self.localcontext and not self.localcontext.get('internal_header',False): + del self.localcontext['internal_header'] + fis = [] + r = _rml_flowable(self.doc,self.localcontext, images=self.images, path=self.path, title=self.title) + story_cnt = 0 + for node_story in node_stories: + if story_cnt > 0: + fis.append(platypus.PageBreak()) + fis += r.render(node_story) + # Reset Page Number with new story tag + fis.append(PageReset()) + story_cnt += 1 + if self.localcontext and self.localcontext.get('internal_header',False): + self.doc_tmpl.afterFlowable(fis) + self.doc_tmpl.build(fis,canvasmaker=NumberedCanvas) + else: + self.doc_tmpl.build(fis) + +def parseNode(rml, localcontext=None, fout=None, images=None, path='.', title=None): + node = etree.XML(rml) + r = _rml_doc(node, localcontext, images, path, title=title) + #try to override some font mappings + try: + from customfonts import SetCustomFonts + SetCustomFonts(r) + except ImportError: + # means there is no custom fonts mapping in this system. + pass + except Exception: + _logger.warning('Cannot set font mapping', exc_info=True) + pass + fp = StringIO() + r.render(fp) + return fp.getvalue() + +def parseString(rml, localcontext=None, fout=None, images=None, path='.', title=None): + node = etree.XML(rml) + r = _rml_doc(node, localcontext, images, path, title=title) + + #try to override some font mappings + try: + from customfonts import SetCustomFonts + SetCustomFonts(r) + except Exception: + pass + + if fout: + fp = file(fout,'wb') + r.render(fp) + fp.close() + return fout + else: + fp = StringIO() + r.render(fp) + return fp.getvalue() + +def trml2pdf_help(): + print 'Usage: trml2pdf input.rml >output.pdf' + print 'Render the standard input (RML) and output a PDF file' + sys.exit(0) + +if __name__=="__main__": + if len(sys.argv)>1: + if sys.argv[1]=='--help': + trml2pdf_help() + print parseString(file(sys.argv[1], 'r').read()), + else: + print 'Usage: trml2pdf input.rml >output.pdf' + print 'Try \'trml2pdf --help\' for more information.' + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/ext/custom-addons/web_printscreen_zb/views/web_printscreen_zb.xml b/ext/custom-addons/web_printscreen_zb/views/web_printscreen_zb.xml new file mode 100644 index 00000000..0386b7d2 --- /dev/null +++ b/ext/custom-addons/web_printscreen_zb/views/web_printscreen_zb.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index e46f6261..64e727b3 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -117,7 +117,8 @@ class Config(): 'cam_custom', 'cam_reports', 'account_cancel', - 'cam_invoice_skonto', + 'cam_invoice_skonto', + #'web_printscreen_zb', #'crm', #'sale', #'cam_hr_overtime', From 6df07dda9dcb3e916e499543dae70f002816c52e Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Tue, 20 Jan 2015 15:52:37 +0100 Subject: [PATCH 03/26] Enabled web_printscreen --- setup/lib/config_at.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index d3109280..7613086d 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -118,7 +118,7 @@ class Config(): 'cam_reports', 'account_cancel', 'cam_invoice_skonto', - #'web_printscreen_zb', + 'web_printscreen_zb', #'crm', #'sale', #'cam_hr_overtime', From 2e816077d135a167476e50645948d12f78909e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Tue, 20 Jan 2015 19:05:39 +0100 Subject: [PATCH 04/26] =?UTF-8?q?w=C3=A4hrungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/lib/cli.py | 3 ++- setup/lib/config_at.py | 7 ++++++- setup/lib/functions.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/setup/lib/cli.py b/setup/lib/cli.py index 5106df6b..d0b015a4 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -57,7 +57,8 @@ def main(): 'set_taxes', 'set_uom', 'set_steuerzuordnung', - 'setup_journals', + 'setup_journals', + 'set_currencies', ] if cmd == 'rollout': diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index c38baa22..a44cee41 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -50,7 +50,12 @@ class Config(): 'Kunde Ausland', 'Kunde EU (ohne USt-ID)', 'Kunde EU Unternehmen (mit USt-ID)', - ] + ] + + # Aktive Währungen + self.valid_currencies = [ + 'EUR', + ] # Allgemeine Einstellungen self.base_config = { diff --git a/setup/lib/functions.py b/setup/lib/functions.py index 13977342..dde397e5 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -264,6 +264,25 @@ class CamadeusFunctions(): wizard_id = self._execute('wizard.multi.charts.accounts', 'create', vals) res = self._execute('wizard.multi.charts.accounts', 'action_next', [wizard_id]) return True + + def set_currencies(self): + """Währungen setzen""" + + c = self.config + + # Set all currencies to active + ids = self._execute('res.currency', 'search', ['|',('active','=',True),('active','=',False)]) + res = self._execute('res.currency', 'write', ids, {'active': True}) + if not res: + return False + + # Set all other UOMs to inactive + inactive_ids = self._execute('res.currency', 'search', [('name','not in',c.valid_currencies)]) + res = self._execute('res.currency', 'write', inactive_ids, {'active': False}) + if not res: + return False + + return True def uninstall_chat(self): """Chat-Modul deinstallieren """ From 96c11e2e7b1f487de0273e271213c1af64cb3aa6 Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Wed, 21 Jan 2015 11:45:28 +0100 Subject: [PATCH 05/26] =?UTF-8?q?Basiskonfiguration=20f=C3=BCr=20Lager=20l?= =?UTF-8?q?aden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup/lib/config_at.py | 5 +++++ setup/lib/functions.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 7613086d..e263f43d 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -70,6 +70,11 @@ class Config(): 'group_purchase_pricelist': True, # Preislisten verwenden } + #Einstellungen Lager + self.stock_config = { + 'group_stock_multiple_locations': True, # Verwalten Sie mehrere Läger und Lagerorte + } + self.sequences = { 'sale.order': { 'number_next_actual': 2000, diff --git a/setup/lib/functions.py b/setup/lib/functions.py index 13977342..cdad1e4d 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -137,7 +137,16 @@ class CamadeusFunctions(): vals = self._execute('sale.config.settings', 'default_get', []) vals.update(self.config.sale_config) wizard_id = self._execute('sale.config.settings', 'create', vals) - return self._execute('sale.config.settings', 'execute', [wizard_id]) + return self._execute('sale.config.settings', 'execute', [wizard_id]) + + def stock_config(self): + """Basiskonfiguration für Lager laden""" + + if hasattr(self.config, 'stock_config'): + vals = self._execute('stock.config.settings', 'default_get', []) + vals.update(self.config.stock_config) + wizard_id = self._execute('stock.config.settings', 'create', vals) + return self._execute('stock.config.settings', 'execute', [wizard_id]) def base_config(self): """Allgemeine Konfiguration laden""" From ce586da49b3e68997af1b218fe7228d1b194c936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Wed, 21 Jan 2015 18:50:30 +0100 Subject: [PATCH 06/26] warehouse bug --- setup/lib/functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/lib/functions.py b/setup/lib/functions.py index dde397e5..034edfa4 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -392,7 +392,7 @@ class CamadeusFunctions(): vals = { 'name': self.config.warehouse_name or self.config.company_data.get('name','Mein Unternehmen') } - warehouse_ids = self._execute('stock.warehouse', 'search', []) + warehouse_ids = self._execute('stock.warehouse', 'search', [('id','=',1)]) return self._execute('stock.warehouse', 'write', warehouse_ids, vals) else: return True From 5ef8d3040d330338e79e150bf88038b243698f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Thu, 22 Jan 2015 18:06:06 +0100 Subject: [PATCH 07/26] purchase, stock config --- setup/lib/cli.py | 2 ++ setup/lib/config_at.py | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/setup/lib/cli.py b/setup/lib/cli.py index d0b015a4..90a15d61 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -52,6 +52,8 @@ def main(): 'set_warehouse', 'base_config', 'sale_config', + 'stock_config', + 'purchase_config', 'set_date_format', 'set_company', 'set_taxes', diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 4d89da7d..1391cedc 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -64,20 +64,22 @@ class Config(): # Einstellungen Verkauf self.sale_config = { - 'group_sale_delivery_address': True, # Verschiedene Adressen für Rechnung und Lieferung - 'group_sale_pricelist': True, # Preislisten verwenden - 'group_discount_per_so_line': True, # Rabatte verwenden - 'group_uom': True, # Verwende Mengeneinheiten + 'group_sale_delivery_address': True, # Verschiedene Adressen für Rechnung und Lieferung + 'group_sale_pricelist': True, # Preislisten verwenden + 'group_discount_per_so_line': True, # Rabatte verwenden + 'group_uom': True, # Verwende Mengeneinheiten } # Einstellungen Einkauf self.purchase_config = { - 'group_purchase_pricelist': True, # Preislisten verwenden + 'group_purchase_pricelist': True, # Preislisten verwenden } #Einstellungen Lager self.stock_config = { 'group_stock_multiple_locations': True, # Verwalten Sie mehrere Läger und Lagerorte + 'group_stock_tracking_lot': False, # Benutze Verpackungen: Paletten, Boxen, ... + 'group_stock_packaging': False, # Ermöglicht die Auswahl einer Verpackung } self.sequences = { From 977cef1577cb572e2da22d54ed73a959443287a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Fri, 23 Jan 2015 13:23:19 +0100 Subject: [PATCH 08/26] dmi scripts: inventory-confirm, set-noupdate --- setup/lib/cli.py | 4 +++- setup/lib/functions.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/setup/lib/cli.py b/setup/lib/cli.py index 90a15d61..3499802f 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -66,7 +66,9 @@ def main(): if cmd == 'rollout': methods = [ 'login', - 'set_dokumentennummern', + 'set_dokumentennummern', + 'set_dmi_noupdate', + 'dmi_confirm_inventory', ] if cmd == 'update': diff --git a/setup/lib/functions.py b/setup/lib/functions.py index a78a8c4b..f527e1b8 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -405,3 +405,24 @@ class CamadeusFunctions(): return self._execute('stock.warehouse', 'write', warehouse_ids, vals) else: return True + + def set_dmi_noupdate(self): + """DMI: Einträge auf 'no update' setzen""" + + domain = [('module','=','cam_dmi'),('noupdate','=',False)] + data_ids = self._execute('ir.model.data', 'search', domain) + + vals = {'noupdate': True} + return self._execute('ir.model.data', 'write', data_ids, vals) + + def dmi_confirm_inventory(self): + """DMI: Lagerstand einbuchen""" + + dummy,inventory_id = self._execute('ir.model.data', 'get_object_reference', 'cam_dmi','inv_init') + + inventory = self._execute('stock.inventory', 'read', inventory_id, ['state']) + + if inventory.get('state','') == 'confirm': + return self._execute('stock.inventory', 'action_done', [inventory_id]) + + return True \ No newline at end of file From de782fe989454d491d5b51483954a5ab7a7a2b45 Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Tue, 27 Jan 2015 13:19:20 +0100 Subject: [PATCH 09/26] =?UTF-8?q?Muster=20f=C3=BCr=20Produktbeschreibung?= =?UTF-8?q?=20ohne=20default=5Fcode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ext/custom-addons/cam_custom/cam_custom.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ext/custom-addons/cam_custom/cam_custom.py b/ext/custom-addons/cam_custom/cam_custom.py index aeb2ff42..bebceb12 100644 --- a/ext/custom-addons/cam_custom/cam_custom.py +++ b/ext/custom-addons/cam_custom/cam_custom.py @@ -78,4 +78,15 @@ class mail_notification(osv.Model): # }) # footer = tools.append_content_to_html(footer, signature_company, plaintext=False, container_tag='div') - return footer \ No newline at end of file + return footer + +# class product_product(osv.osv): +# _inherit = 'product.product' +# +# def name_get(self, cr, user, ids, context=None): +# if context is None: +# context = {} +# c = context.copy() +# c.update({'display_default_code': False}) +# return super(product_product, self).name_get(cr, user, ids, context=c) + \ No newline at end of file From c2445bcc1c1e1293ed53adbf7a2009154f843a69 Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Tue, 27 Jan 2015 16:54:39 +0100 Subject: [PATCH 10/26] product_code in product_supplierinfo ausgeblendet --- ext/custom-addons/cam_custom/cam_custom_view.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ext/custom-addons/cam_custom/cam_custom_view.xml b/ext/custom-addons/cam_custom/cam_custom_view.xml index e2cf755e..62c1597b 100644 --- a/ext/custom-addons/cam_custom/cam_custom_view.xml +++ b/ext/custom-addons/cam_custom/cam_custom_view.xml @@ -64,5 +64,16 @@ + + product.supplierinfo.form.view + product.supplierinfo + + + + + + + + From aa3aaaea9ff68aa9a7107e7811fe670fa02c281f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Tue, 27 Jan 2015 17:50:12 +0100 Subject: [PATCH 11/26] disabled menus --- ext/custom-addons/cam_custom/cam_custom.py | 27 ++++++++++++++++++++++ setup/lib/functions.py | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ext/custom-addons/cam_custom/cam_custom.py b/ext/custom-addons/cam_custom/cam_custom.py index aeb2ff42..785b34b2 100644 --- a/ext/custom-addons/cam_custom/cam_custom.py +++ b/ext/custom-addons/cam_custom/cam_custom.py @@ -27,6 +27,33 @@ from openerp import SUPERUSER_ID from openerp import tools from lxml import etree +DISABLED_MENUS = [ +] + +class ir_ui_menu(osv.osv): + _inherit = 'ir.ui.menu' + + @tools.ormcache(skiparg=2) + def get_disabled_menu_ids(self, cr, uid, context=None): + data_obj = self.pool.get('ir.model.data') + + menu_ids = [] + for menu in DISABLED_MENUS: + module,xml_id = menu.split('.') + menu = data_obj.get_object(cr, uid, module, xml_id) + if menu: + menu_ids.append(menu.id) + return menu_ids + + def _filter_visible_menus(self, cr, uid, ids, context=None): + if uid != 1: + disabled_ids = self.get_disabled_menu_ids(cr, uid) + + ids = [id for id in ids if id not in disabled_ids] + + ids = super(ir_ui_menu, self)._filter_visible_menus(cr, uid, ids, context) + return ids + class res_partner(osv.osv): _inherit = 'res.partner' diff --git a/setup/lib/functions.py b/setup/lib/functions.py index f527e1b8..e2d581ce 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -130,6 +130,7 @@ class CamadeusFunctions(): vals.update(self.config.purchase_config) wizard_id = self._execute('purchase.config.settings', 'create', vals) return self._execute('purchase.config.settings', 'execute', [wizard_id]) + return True def sale_config(self): """Basiskonfiguration für Verkauf laden""" @@ -146,7 +147,8 @@ class CamadeusFunctions(): vals = self._execute('stock.config.settings', 'default_get', []) vals.update(self.config.stock_config) wizard_id = self._execute('stock.config.settings', 'create', vals) - return self._execute('stock.config.settings', 'execute', [wizard_id]) + return self._execute('stock.config.settings', 'execute', [wizard_id]) + return True def base_config(self): """Allgemeine Konfiguration laden""" From bae08695a265982be58ea4393a96e85a799f22a5 Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Fri, 30 Jan 2015 12:14:36 +0100 Subject: [PATCH 12/26] Disabled default_code in name_get --- ext/custom-addons/cam_custom/cam_custom.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ext/custom-addons/cam_custom/cam_custom.py b/ext/custom-addons/cam_custom/cam_custom.py index bebceb12..39b534c8 100644 --- a/ext/custom-addons/cam_custom/cam_custom.py +++ b/ext/custom-addons/cam_custom/cam_custom.py @@ -34,7 +34,17 @@ class res_partner(osv.osv): def fields_view_get_address(self, arch): """ verhindert das Überschreiben von address_format """ return arch - + +class product_product(osv.osv): + _inherit = 'product.product' + + def name_get(self, cr, user, ids, context=None): + if context is None: + context = {} + c = context.copy() + c.update({'display_default_code': False}) + return super(product_product, self).name_get(cr, user, ids, context=c) + class mail_notification(osv.Model): _inherit = 'mail.notification' From ccbb24d84cb7ed28cb8daf0d373b7df22e447092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Fri, 30 Jan 2015 15:19:41 +0100 Subject: [PATCH 13/26] gutschriftensequence, incoterms, --- setup/lib/cli.py | 10 ++++++- setup/lib/config_at.py | 20 ++++++++++---- setup/lib/functions.py | 62 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/setup/lib/cli.py b/setup/lib/cli.py index 3499802f..9395f041 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -13,7 +13,7 @@ def main(): argv = sys.argv[1:] if not len(argv) == 2: - if len(argv) == 3 and argv[1] == 'update': # 'update' requires additional param 'module_name' + if len(argv) == 3 and argv[1] in ['update','install']: # 'update' requires additional param 'module_name' pass else: _usage() @@ -53,6 +53,7 @@ def main(): 'base_config', 'sale_config', 'stock_config', + 'set_incoterms', 'purchase_config', 'set_date_format', 'set_company', @@ -78,6 +79,13 @@ def main(): 'update_module', ] + if cmd == 'install': + instance.config.module_name = argv[2] + methods = [ + 'login', + 'install_module', + ] + if cmd == 'update_modules': methods = [ 'login', diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 1391cedc..2e8e700d 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -81,26 +81,29 @@ class Config(): 'group_stock_tracking_lot': False, # Benutze Verpackungen: Paletten, Boxen, ... 'group_stock_packaging': False, # Ermöglicht die Auswahl einer Verpackung } + + # Wenn gesetzt, teilen sich Gutschriften und Rechnungen den selben Nummernkreis + self.refund_invoice_sequence = True self.sequences = { 'sale.order': { - 'number_next_actual': 2000, + 'number_next_actual': 1, 'prefix': 'A-', 'padding': 5, }, # 'work.order': { -# 'number_next_actual': 100, +# 'number_next_actual': 1, # 'prefix': 'AS-', # 'padding': 5, # }, # 'picking.out': { -# 'number_next_actual': 2000, +# 'number_next_actual': 1, # 'prefix': 'L-', # 'padding': 5, # }, # 'purchase.order': { -# 'number_next_actual': 2000, -# 'prefix': 'PO-', +# 'number_next_actual': 1, +# 'prefix': 'B-', # 'padding': 5, # }, # 'account.invoice': { @@ -116,6 +119,13 @@ class Config(): #'product.product_uom_litre': 'l', #'product.product_uom_hour': 'h', } + + #Lieferbedingungen + self.incoterms = { + ('Ab Werk', 'ABW'), + ('Botendienst', 'BOT'), + ('Zustellung', 'ZUS'), + } # Soll das Ändern einer Rechnung im Nachhinein erlaubt sein? self.allow_cancel_invoice = True diff --git a/setup/lib/functions.py b/setup/lib/functions.py index e2d581ce..5fe2ab43 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -149,6 +149,35 @@ class CamadeusFunctions(): wizard_id = self._execute('stock.config.settings', 'create', vals) return self._execute('stock.config.settings', 'execute', [wizard_id]) return True + + def set_incoterms(self): + """Lieferbedingungen setzen""" + + if hasattr(self.config, 'incoterms'): + terms = self.config.incoterms + + + for name,code in terms: + existing_ids = self._execute('stock.incoterms', 'search', ['|',('active','=',True),('active','=',False),('code','=',code)]) + if existing_ids: + vals = { + 'active': True, + 'name': name, + } + self._execute('stock.incoterms', 'write', existing_ids, vals) + else: + vals = { + 'name': name, + 'code': code, + } + self._execute('stock.incoterms', 'create', vals) + + codes = [code for name,code in terms] + inactive_ids = self._execute('stock.incoterms', 'search', [('code','not in',codes)]) + self._execute('stock.incoterms', 'write', inactive_ids, {'active': False}) + + + return True def base_config(self): """Allgemeine Konfiguration laden""" @@ -181,7 +210,7 @@ class CamadeusFunctions(): # Lieferschein if seq_dict.get('picking.out',False): - picking_type_ids = self._execute('stock.picking.type', 'search', []) + picking_type_ids = self._execute('stock.picking.type', 'search', [('code','=','outgoing')]) picking_types = self._execute('stock.picking.type', 'read', picking_type_ids, ['sequence_id']) s_ids = [t['sequence_id'][0] for t in picking_types] if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('picking.out')): @@ -217,10 +246,26 @@ class CamadeusFunctions(): if len(j_ids) != 1: return False journals = self._execute('account.journal', 'read', j_ids, ['sequence_id']) - s_ids = [t['sequence_id'][0] for t in journals] - if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('account.invoice')): + s_id = journals[0]['sequence_id'][0] + if not self._execute('ir.sequence', 'write', [s_id], seq_dict.get('account.invoice')): return False + # Setzen Gutschriftenkreis + if self.config.refund_invoice_sequence: + j_ids = self._execute('account.journal', 'search', [('code','=','VK')]) + if len(j_ids) != 1: + return False + journals = self._execute('account.journal', 'read', j_ids, ['sequence_id']) + s_id = journals[0]['sequence_id'][0] + + gj_ids = self._execute('account.journal', 'search', [('code','=','GSV')]) + if len(gj_ids) != 1: + return False + vals = { + 'sequence_id': s_id, + } + self._execute('account.journal', 'write', gj_ids,vals) + return True def set_admin_rights(self): @@ -364,6 +409,17 @@ class CamadeusFunctions(): res = self._execute('base.module.upgrade', 'upgrade_module', []) return True + def install_module(self): + """Installiere Modul""" + module_name = self.config.module_name + mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','uninstalled')]) + if not len(mod_ids) == 1: + raise "Module '%s' not found or is not in state 'uninstalled'." % module_name + + res = self._execute('ir.module.module', 'button_install', mod_ids) + res = self._execute('base.module.upgrade', 'upgrade_module', []) + return True + def update_modules(self): """Verfügbare Module updaten""" From 90dc966fc9abe558cffe2fb7dcd792606ddd47ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Fri, 30 Jan 2015 15:22:21 +0100 Subject: [PATCH 14/26] decimal places price --- setup/lib/cli.py | 55 +++++++++++++++++++++--------------------- setup/lib/config_at.py | 5 ++-- setup/lib/functions.py | 12 ++++++++- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/setup/lib/cli.py b/setup/lib/cli.py index 9395f041..03e7a21d 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -41,7 +41,7 @@ def main(): 'install_module_sale', 'setup_accounting', 'setup_accounting2', - 'set_admin_rights', + 'set_admin_rights', ] if cmd == 'setup': @@ -55,61 +55,62 @@ def main(): 'stock_config', 'set_incoterms', 'purchase_config', - 'set_date_format', - 'set_company', - 'set_taxes', - 'set_uom', - 'set_steuerzuordnung', - 'setup_journals', - 'set_currencies', + 'set_date_format', + 'set_company', + 'set_taxes', + 'set_uom', + 'set_steuerzuordnung', + 'setup_journals', + 'set_currencies', + 'set_decimal_price', ] if cmd == 'rollout': methods = [ 'login', - 'set_dokumentennummern', - 'set_dmi_noupdate', - 'dmi_confirm_inventory', - ] - + 'set_dokumentennummern', + 'set_dmi_noupdate', + 'dmi_confirm_inventory', + ] + if cmd == 'update': instance.config.module_name = argv[2] methods = [ 'login', - 'update_module', - ] + 'update_module', + ] if cmd == 'install': instance.config.module_name = argv[2] methods = [ 'login', - 'install_module', - ] + 'install_module', + ] if cmd == 'update_modules': methods = [ 'login', - 'update_modules', - ] + 'update_modules', + ] if cmd == 'update_all': methods = [ 'login', - 'update_all', - ] + 'update_all', + ] if not methods: _usage() - + print env - - for method in methods: + + for method in methods: res = getattr(instance, method)() print "%s: %s" % (res and "OK " or "ERROR ", getattr(instance, method).__doc__) if not res: return False - + print "\nAbgeschlossen." - + if __name__ == "__main__": - main() + main() diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 2e8e700d..d7f2e536 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -7,8 +7,9 @@ class Config(): self.chart_of_accounts = 'l10n_at' self.sales_tax = '20% MwSt' self.purchase_tax = '20% VSt' - self.chart_template_id = 2 # Austrian Chart of Account - + self.chart_template_id = 2 # Austrian Chart of Account + self.digits = 2 #Nachkommastellen Preis + self.company_data = { 'name': 'Camadeus GmbH', 'street': 'Kriehubergasse 16', diff --git a/setup/lib/functions.py b/setup/lib/functions.py index 5fe2ab43..489d2411 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -483,4 +483,14 @@ class CamadeusFunctions(): if inventory.get('state','') == 'confirm': return self._execute('stock.inventory', 'action_done', [inventory_id]) - return True \ No newline at end of file + return True + + def set_decimal_price(self): + """Dezimalstellen Preis setzen""" + + # Set all currencies to active + ids = self._execute('decimal.precision', 'search', [('name','=','Product Price')]) + res = self._execute('decimal.precision', 'write', ids, {'digits': self.config.digits}) + if not res: + return False + return True \ No newline at end of file From dfd2f93c27371cf0e23418a455e0fef53406ef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Thu, 5 Feb 2015 17:26:39 +0100 Subject: [PATCH 15/26] update soft-limit --- ext/config/odoo-server.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/config/odoo-server.conf b/ext/config/odoo-server.conf index dd0b1e92..3803c5f4 100644 --- a/ext/config/odoo-server.conf +++ b/ext/config/odoo-server.conf @@ -34,3 +34,6 @@ limit_time_real = 6000 # if DB > 150MB, otherwise "AccessDenied" error occurs # 10 GB limit_memory_hard = 10000000000 + +# Use a new worker for the next request if 300MB is reached +limit_memory_soft = 300000000 \ No newline at end of file From 5f57eb348254d1b1f7d1034300db2c6af7ae7aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Wed, 11 Feb 2015 17:38:17 +0100 Subject: [PATCH 16/26] update mem limit, fehler bei sequencen --- ext/config/odoo-server.conf | 5 +++-- ext/custom-addons/cam_custom/cam_custom_view.xml | 2 +- setup/lib/config_at.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/config/odoo-server.conf b/ext/config/odoo-server.conf index 3803c5f4..f0b68fe6 100644 --- a/ext/config/odoo-server.conf +++ b/ext/config/odoo-server.conf @@ -35,5 +35,6 @@ limit_time_real = 6000 # 10 GB limit_memory_hard = 10000000000 -# Use a new worker for the next request if 300MB is reached -limit_memory_soft = 300000000 \ No newline at end of file +# Use a new worker for the next request if 400MB is reached +# The worker will be recycled after the current request +limit_memory_soft = 400000000 \ No newline at end of file diff --git a/ext/custom-addons/cam_custom/cam_custom_view.xml b/ext/custom-addons/cam_custom/cam_custom_view.xml index 62c1597b..2590defa 100644 --- a/ext/custom-addons/cam_custom/cam_custom_view.xml +++ b/ext/custom-addons/cam_custom/cam_custom_view.xml @@ -55,7 +55,7 @@ - + diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index d7f2e536..54dcbdc3 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -97,7 +97,7 @@ class Config(): # 'prefix': 'AS-', # 'padding': 5, # }, -# 'picking.out': { +# FEHLER da gleich für alle Vorgangstypen!!! 'picking.out': { # 'number_next_actual': 1, # 'prefix': 'L-', # 'padding': 5, From 8b8765fc7b3e666a3632ec45e55d498e9626ccdb Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Mon, 16 Feb 2015 14:31:46 +0100 Subject: [PATCH 17/26] Anpassung Nummernkreise Lieferschein OUT/IN/INT --- setup/lib/config_at.py | 20 +++++++++++++++----- setup/lib/functions.py | 31 +++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/setup/lib/config_at.py b/setup/lib/config_at.py index 54dcbdc3..eb9dc884 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config_at.py @@ -97,11 +97,21 @@ class Config(): # 'prefix': 'AS-', # 'padding': 5, # }, -# FEHLER da gleich für alle Vorgangstypen!!! 'picking.out': { -# 'number_next_actual': 1, -# 'prefix': 'L-', -# 'padding': 5, -# }, +# 'picking.out': { +# #'number_next_actual': 1, +# 'prefix': 'LS/', +# 'padding': 4, +# }, +# 'picking.in': { +# #'number_next_actual': 1, +# 'prefix': 'LS/IN/', +# 'padding': 4, +# }, +# 'picking.int': { +# #'number_next_actual': 1, +# 'prefix': 'LS/INT/', +# 'padding': 4, +# }, # 'purchase.order': { # 'number_next_actual': 1, # 'prefix': 'B-', diff --git a/setup/lib/functions.py b/setup/lib/functions.py index 489d2411..8f7a9e4e 100755 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -203,18 +203,33 @@ class CamadeusFunctions(): res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install) return True + def _set_picking_sequence_prefix(self, code, value): + seq_dict = self.config.sequences + + #Hauptsequenz des Picking Types mit diesem code anpassen + picking_type_id = self._execute('stock.picking.type', 'search', [('code','=',code)], 0, 1, 'id')[0] + picking_type = self._execute('stock.picking.type', 'read', picking_type_id, ['sequence_id']) + s_id = picking_type['sequence_id'][0] + if not self._execute('ir.sequence', 'write', s_id, seq_dict.get(value)): + return False + + #Allen Picking Types mit diesem code die Haupsequenz geben + picking_type_ids = self._execute('stock.picking.type', 'search', [('code','=',code)]) + if not self._execute('stock.picking.type', 'write', picking_type_ids, {'sequence_id': s_id}): + return False + def set_dokumentennummern(self): """Dokumentennummern setzen""" seq_dict = self.config.sequences - # Lieferschein - if seq_dict.get('picking.out',False): - picking_type_ids = self._execute('stock.picking.type', 'search', [('code','=','outgoing')]) - picking_types = self._execute('stock.picking.type', 'read', picking_type_ids, ['sequence_id']) - s_ids = [t['sequence_id'][0] for t in picking_types] - if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('picking.out')): - return False + # Lieferschein + if seq_dict.get('picking.out',False): + self._set_picking_sequence_prefix('outgoing', 'picking.out') + if seq_dict.get('picking.in',False): + self._set_picking_sequence_prefix('incoming', 'picking.in') + if seq_dict.get('picking.int',False): + self._set_picking_sequence_prefix('internal', 'picking.int') # Angebot if seq_dict.get('sale.order',False): @@ -493,4 +508,4 @@ class CamadeusFunctions(): res = self._execute('decimal.precision', 'write', ids, {'digits': self.config.digits}) if not res: return False - return True \ No newline at end of file + return True From 0e9ec565a208449ebaf3339ce454e0db5bd25a1e Mon Sep 17 00:00:00 2001 From: Stefan Katzensteiner Date: Thu, 19 Feb 2015 14:39:55 +0100 Subject: [PATCH 18/26] =?UTF-8?q?Neues=20Standardtemplate=20f=C3=BCr=20Rec?= =?UTF-8?q?hung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cam_reports/report/account.invoice.rml | 200 ++++++++++-------- ext/custom-addons/cam_reports/report/page.rml | 80 ++++--- 2 files changed, 152 insertions(+), 128 deletions(-) diff --git a/ext/custom-addons/cam_reports/report/account.invoice.rml b/ext/custom-addons/cam_reports/report/account.invoice.rml index fe1b2cd0..a4a8ec3d 100644 --- a/ext/custom-addons/cam_reports/report/account.invoice.rml +++ b/ext/custom-addons/cam_reports/report/account.invoice.rml @@ -1,11 +1,6 @@ - -