Merge branch 'master' of git:~/gitrepos/cam-template

develop
Stefan Katzensteiner 2015-05-04 13:34:04 +02:00
commit 8533d2b987
57 changed files with 14784 additions and 5106 deletions

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/INSTANCE/ext/odoo/odoo.py"/>
<listEntry value="/INSTANCE/ext/odoo/odoo-dev.py"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:INSTANCE/ext/odoo/odoo.py}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:INSTANCE/ext/odoo/odoo-dev.py}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value=""/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-c dev/odoo-server-dev-${env_var:CAM_USER}.conf --db-filter=&quot;^INSTANCE.*&quot;"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,883 +0,0 @@
<transformation>
<info>
<name>VAT-Lookup</name>
<description/>
<extended_description/>
<trans_version/>
<trans_type>Normal</trans_type>
<trans_status>0</trans_status>
<directory>&#x2f;</directory>
<parameters>
</parameters>
<log>
<trans-log-table><connection/>
<schema/>
<table/>
<size_limit_lines/>
<interval/>
<timeout_days/>
<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STATUS</id><enabled>Y</enabled><name>STATUS</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name><subject/></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name><subject/></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name><subject/></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name><subject/></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name><subject/></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name><subject/></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>STARTDATE</id><enabled>Y</enabled><name>STARTDATE</name></field><field><id>ENDDATE</id><enabled>Y</enabled><name>ENDDATE</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>DEPDATE</id><enabled>Y</enabled><name>DEPDATE</name></field><field><id>REPLAYDATE</id><enabled>Y</enabled><name>REPLAYDATE</name></field><field><id>LOG_FIELD</id><enabled>Y</enabled><name>LOG_FIELD</name></field><field><id>EXECUTING_SERVER</id><enabled>N</enabled><name>EXECUTING_SERVER</name></field><field><id>EXECUTING_USER</id><enabled>N</enabled><name>EXECUTING_USER</name></field><field><id>CLIENT</id><enabled>N</enabled><name>CLIENT</name></field></trans-log-table>
<perf-log-table><connection/>
<schema/>
<table/>
<interval/>
<timeout_days/>
<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>SEQ_NR</id><enabled>Y</enabled><name>SEQ_NR</name></field><field><id>LOGDATE</id><enabled>Y</enabled><name>LOGDATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>INPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>INPUT_BUFFER_ROWS</name></field><field><id>OUTPUT_BUFFER_ROWS</id><enabled>Y</enabled><name>OUTPUT_BUFFER_ROWS</name></field></perf-log-table>
<channel-log-table><connection/>
<schema/>
<table/>
<timeout_days/>
<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>LOGGING_OBJECT_TYPE</id><enabled>Y</enabled><name>LOGGING_OBJECT_TYPE</name></field><field><id>OBJECT_NAME</id><enabled>Y</enabled><name>OBJECT_NAME</name></field><field><id>OBJECT_COPY</id><enabled>Y</enabled><name>OBJECT_COPY</name></field><field><id>REPOSITORY_DIRECTORY</id><enabled>Y</enabled><name>REPOSITORY_DIRECTORY</name></field><field><id>FILENAME</id><enabled>Y</enabled><name>FILENAME</name></field><field><id>OBJECT_ID</id><enabled>Y</enabled><name>OBJECT_ID</name></field><field><id>OBJECT_REVISION</id><enabled>Y</enabled><name>OBJECT_REVISION</name></field><field><id>PARENT_CHANNEL_ID</id><enabled>Y</enabled><name>PARENT_CHANNEL_ID</name></field><field><id>ROOT_CHANNEL_ID</id><enabled>Y</enabled><name>ROOT_CHANNEL_ID</name></field></channel-log-table>
<step-log-table><connection/>
<schema/>
<table/>
<timeout_days/>
<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>TRANSNAME</id><enabled>Y</enabled><name>TRANSNAME</name></field><field><id>STEPNAME</id><enabled>Y</enabled><name>STEPNAME</name></field><field><id>STEP_COPY</id><enabled>Y</enabled><name>STEP_COPY</name></field><field><id>LINES_READ</id><enabled>Y</enabled><name>LINES_READ</name></field><field><id>LINES_WRITTEN</id><enabled>Y</enabled><name>LINES_WRITTEN</name></field><field><id>LINES_UPDATED</id><enabled>Y</enabled><name>LINES_UPDATED</name></field><field><id>LINES_INPUT</id><enabled>Y</enabled><name>LINES_INPUT</name></field><field><id>LINES_OUTPUT</id><enabled>Y</enabled><name>LINES_OUTPUT</name></field><field><id>LINES_REJECTED</id><enabled>Y</enabled><name>LINES_REJECTED</name></field><field><id>ERRORS</id><enabled>Y</enabled><name>ERRORS</name></field><field><id>LOG_FIELD</id><enabled>N</enabled><name>LOG_FIELD</name></field></step-log-table>
<metrics-log-table><connection/>
<schema/>
<table/>
<timeout_days/>
<field><id>ID_BATCH</id><enabled>Y</enabled><name>ID_BATCH</name></field><field><id>CHANNEL_ID</id><enabled>Y</enabled><name>CHANNEL_ID</name></field><field><id>LOG_DATE</id><enabled>Y</enabled><name>LOG_DATE</name></field><field><id>METRICS_DATE</id><enabled>Y</enabled><name>METRICS_DATE</name></field><field><id>METRICS_CODE</id><enabled>Y</enabled><name>METRICS_CODE</name></field><field><id>METRICS_DESCRIPTION</id><enabled>Y</enabled><name>METRICS_DESCRIPTION</name></field><field><id>METRICS_SUBJECT</id><enabled>Y</enabled><name>METRICS_SUBJECT</name></field><field><id>METRICS_TYPE</id><enabled>Y</enabled><name>METRICS_TYPE</name></field><field><id>METRICS_VALUE</id><enabled>Y</enabled><name>METRICS_VALUE</name></field></metrics-log-table>
</log>
<maxdate>
<connection/>
<table/>
<field/>
<offset>0.0</offset>
<maxdiff>0.0</maxdiff>
</maxdate>
<size_rowset>10000</size_rowset>
<sleep_time_empty>50</sleep_time_empty>
<sleep_time_full>50</sleep_time_full>
<unique_connections>N</unique_connections>
<feedback_shown>Y</feedback_shown>
<feedback_size>50000</feedback_size>
<using_thread_priorities>Y</using_thread_priorities>
<shared_objects_file/>
<capture_step_performance>N</capture_step_performance>
<step_performance_capturing_delay>1000</step_performance_capturing_delay>
<step_performance_capturing_size_limit>100</step_performance_capturing_size_limit>
<dependencies>
</dependencies>
<partitionschemas>
</partitionschemas>
<slaveservers>
</slaveservers>
<clusterschemas>
</clusterschemas>
<created_user>-</created_user>
<created_date>2014&#x2f;12&#x2f;30 12&#x3a;25&#x3a;19.832</created_date>
<modified_user>-</modified_user>
<modified_date>2015&#x2f;01&#x2f;13 16&#x3a;28&#x3a;08.336</modified_date>
</info>
<notepads>
</notepads>
<order>
<hop> <from>REST Client</from><to>Get data from XML</to><enabled>Y</enabled> </hop>
<hop> <from>kunden_20150107.csv</from><to>Select values</to><enabled>Y</enabled> </hop>
<hop> <from>ieferanten_20150107.csv</from><to>Select values 2</to><enabled>Y</enabled> </hop>
<hop> <from>Select values</from><to>Create URL</to><enabled>Y</enabled> </hop>
<hop> <from>Select values 2</from><to>Create URL</to><enabled>Y</enabled> </hop>
<hop> <from>Create URL</from><to>REST Client</to><enabled>Y</enabled> </hop>
<hop> <from>Get data from XML</from><to>Aufbereiten</to><enabled>Y</enabled> </hop>
<hop> <from>Aufbereiten</from><to>vat_lookup.csv</to><enabled>Y</enabled> </hop>
</order>
<step>
<name>Aufbereiten</name>
<type>UserDefinedJavaClass</type>
<description/>
<distribute>N</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<definitions>
<definition>
<class_type>TRANSFORM_CLASS</class_type>
<class_name>Processor</class_name>
<class_source><![CDATA[public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
Object[] out = createOutputRow(r, data.outputRowMeta.size());
// Direct Mappings:
get(Fields.Out, "vat_old").setValue(out, get(Fields.In, "vat_old").getString(r));
String cc = get(Fields.In, "country_code").getString(r);
String valid = get(Fields.In, "valid").getString(r);
String vatnr = get(Fields.In, "vatnr").getString(r);
String vat_new = "";
if (valid.equals("true")) {
vat_new = cc + vatnr;
}
get(Fields.Out, "vat_new").setValue(out, vat_new);
// Send the row on to the next step.
putRow(data.outputRowMeta, out);
return true;
}]]></class_source>
</definition>
</definitions>
<fields>
<field>
<field_name>vat_old</field_name>
<field_type>String</field_type>
<field_length>-1</field_length>
<field_precision>-1</field_precision>
</field>
<field>
<field_name>vat_new</field_name>
<field_type>String</field_type>
<field_length>-1</field_length>
<field_precision>-1</field_precision>
</field>
</fields><clear_result_fields>Y</clear_result_fields>
<info_steps></info_steps><target_steps></target_steps><usage_parameters></usage_parameters> <cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>211</xloc>
<yloc>467</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>Create URL</name>
<type>UserDefinedJavaClass</type>
<description/>
<distribute>N</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<definitions>
<definition>
<class_type>TRANSFORM_CLASS</class_type>
<class_name>Processor</class_name>
<class_source><![CDATA[public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
Object[] out = createOutputRow(r, data.outputRowMeta.size());
// Direct Mappings:
// For every row
String vat = get(Fields.In, "vat").getString(r);
if (vat != null) {
vat = vat.replaceAll("\\s+","");
// http://vatid.eu/check/<country_code>/<vat_number>
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;
}]]></class_source>
</definition>
</definitions>
<fields>
<field>
<field_name>help_url</field_name>
<field_type>String</field_type>
<field_length>-1</field_length>
<field_precision>-1</field_precision>
</field>
<field>
<field_name>vat_old</field_name>
<field_type>String</field_type>
<field_length>-1</field_length>
<field_precision>-1</field_precision>
</field>
</fields><clear_result_fields>Y</clear_result_fields>
<info_steps></info_steps><target_steps></target_steps><usage_parameters></usage_parameters> <cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>214</xloc>
<yloc>219</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>Get data from XML</name>
<type>getXMLData</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<include>N</include>
<include_field/>
<rownum>N</rownum>
<addresultfile>N</addresultfile>
<namespaceaware>N</namespaceaware>
<ignorecomments>N</ignorecomments>
<readurl>N</readurl>
<validating>N</validating>
<usetoken>N</usetoken>
<IsIgnoreEmptyFile>N</IsIgnoreEmptyFile>
<doNotFailIfNoFile>Y</doNotFailIfNoFile>
<rownum_field/>
<encoding>UTF-8</encoding>
<file>
<name/>
<filemask/>
<exclude_filemask/>
<file_required>N</file_required>
<include_subfolders>N</include_subfolders>
</file>
<fields>
<field>
<name>valid</name>
<xpath>&#x2f;response&#x2f;valid</xpath>
<element_type>node</element_type>
<result_type>valueof</result_type>
<type>None</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
</field>
<field>
<name>vatnr</name>
<xpath>&#x2f;response&#x2f;vat-number</xpath>
<element_type>node</element_type>
<result_type>valueof</result_type>
<type>None</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
</field>
<field>
<name>country_code</name>
<xpath>&#x2f;response&#x2f;country-code</xpath>
<element_type>node</element_type>
<result_type>valueof</result_type>
<type>None</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
<repeat>N</repeat>
</field>
</fields>
<limit>0</limit>
<loopxpath>&#x2f;response&#x2f;valid</loopxpath>
<IsInFields>Y</IsInFields>
<IsAFile>N</IsAFile>
<XmlField>help_result</XmlField>
<prunePath/>
<shortFileFieldName/>
<pathFieldName/>
<hiddenFieldName/>
<lastModificationTimeFieldName/>
<uriNameFieldName/>
<rootUriNameFieldName/>
<extensionFieldName/>
<sizeFieldName/>
<cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>213</xloc>
<yloc>380</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>REST Client</name>
<type>Rest</type>
<description/>
<distribute>N</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<applicationType>TEXT PLAIN</applicationType>
<method>GET</method>
<url/>
<urlInField>Y</urlInField>
<dynamicMethod>N</dynamicMethod>
<methodFieldName/>
<urlField>help_url</urlField>
<bodyField/>
<httpLogin/>
<httpPassword>Encrypted </httpPassword>
<proxyHost/>
<proxyPort/>
<preemptive>N</preemptive>
<trustStoreFile/>
<trustStorePassword>Encrypted </trustStorePassword>
<headers>
</headers>
<parameters>
</parameters>
<result>
<name>help_result</name>
<code>help_resultcode</code>
<response_time/>
</result>
<cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>212</xloc>
<yloc>287</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>Select values</name>
<type>SelectValues</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields> <field> <name>Steuernummer</name>
<rename>vat</rename>
<length>-2</length>
<precision>-2</precision>
</field> <select_unspecified>N</select_unspecified>
</fields> <cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>124</xloc>
<yloc>159</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>Select values 2</name>
<type>SelectValues</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<fields> <field> <name>Steuer Nr.</name>
<rename>vat</rename>
<length>-2</length>
<precision>-2</precision>
</field> <select_unspecified>N</select_unspecified>
</fields> <cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>290</xloc>
<yloc>155</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>ieferanten_20150107.csv</name>
<type>CsvInput</type>
<description/>
<distribute>N</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<filename>&#x24;&#x7b;GITREPOS&#x7d;&#x2f;input&#x2f;lieferanten_20150107.csv</filename>
<filename_field/>
<rownum_field/>
<include_filename>N</include_filename>
<separator>,</separator>
<enclosure>&#x22;</enclosure>
<header>Y</header>
<buffer_size>50000</buffer_size>
<lazy_conversion>Y</lazy_conversion>
<add_filename_result>N</add_filename_result>
<parallel>N</parallel>
<newline_possible>N</newline_possible>
<encoding/>
<fields>
<field>
<name>Lieferanten Nr</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Suchname</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Bezeichnung</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Firmenname</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Ansprechpartner</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Strasse</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>PLZ</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Stadt</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Land</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Code</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Steuer Nr.</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Mail</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
</fields>
<cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>282</xloc>
<yloc>68</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>kunden_20150107.csv</name>
<type>CsvInput</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<filename>&#x24;&#x7b;GITREPOS&#x7d;&#x2f;input&#x2f;kunden_20150107.csv</filename>
<filename_field/>
<rownum_field/>
<include_filename>N</include_filename>
<separator>,</separator>
<enclosure>&#x22;</enclosure>
<header>Y</header>
<buffer_size>50000</buffer_size>
<lazy_conversion>Y</lazy_conversion>
<add_filename_result>N</add_filename_result>
<parallel>N</parallel>
<newline_possible>N</newline_possible>
<encoding/>
<fields>
<field>
<name>Kundennr</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Suchname</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Type</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Name</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Ansprechpartner</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Adresse</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>PLZ</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Ort</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Land</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Telefon</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Fax</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>mail</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Steuernummer</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Rechnung per Mail</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
<field>
<name>Zahlungsziel</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<length>-1</length>
<precision>-1</precision>
<trim_type>none</trim_type>
</field>
</fields>
<cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>127</xloc>
<yloc>69</yloc>
<draw>Y</draw>
</GUI>
</step>
<step>
<name>vat_lookup.csv</name>
<type>TextFileOutput</type>
<description/>
<distribute>Y</distribute>
<custom_distribution/>
<copies>1</copies>
<partitioning>
<method>none</method>
<schema_name/>
</partitioning>
<separator>,</separator>
<enclosure>&#x22;</enclosure>
<enclosure_forced>N</enclosure_forced>
<enclosure_fix_disabled>N</enclosure_fix_disabled>
<header>Y</header>
<footer>N</footer>
<format>DOS</format>
<compression>None</compression>
<encoding>UTF-8</encoding>
<endedLine/>
<fileNameInField>N</fileNameInField>
<fileNameField/>
<create_parent_folder>Y</create_parent_folder>
<file>
<name>&#x24;&#x7b;GITREPOS&#x7d;&#x2f;cam_dmi&#x2f;vat_lookup</name>
<is_command>N</is_command>
<servlet_output>N</servlet_output>
<do_not_open_new_file_init>N</do_not_open_new_file_init>
<extention>csv</extention>
<append>N</append>
<split>N</split>
<haspartno>N</haspartno>
<add_date>N</add_date>
<add_time>N</add_time>
<SpecifyFormat>N</SpecifyFormat>
<date_time_format/>
<add_to_result_filenames>Y</add_to_result_filenames>
<pad>N</pad>
<fast_dump>N</fast_dump>
<splitevery>0</splitevery>
</file>
<fields>
<field>
<name>vat_old</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<nullif/>
<trim_type>none</trim_type>
<length>-1</length>
<precision>-1</precision>
</field>
<field>
<name>vat_new</name>
<type>String</type>
<format/>
<currency/>
<decimal/>
<group/>
<nullif/>
<trim_type>none</trim_type>
<length>-1</length>
<precision>-1</precision>
</field>
</fields>
<cluster_schema/>
<remotesteps> <input> </input> <output> </output> </remotesteps> <GUI>
<xloc>208</xloc>
<yloc>587</yloc>
<draw>Y</draw>
</GUI>
</step>
<step_error_handling>
</step_error_handling>
<slave-step-copy-partition-distribution>
</slave-step-copy-partition-distribution>
<slave_transformation>N</slave_transformation>
</transformation>

View File

@ -4,11 +4,12 @@ xmlrpc_port = 8080
; This is the password that allows database operations:
; admin_passwd = admin
db_host = False
db_port = 5436
db_port = 5432
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons,dev/dmi/run1
addons_path = ext/odoo/addons,ext/custom-addons,dmi/run1
timezone = Europe/Brussels
#dbfilter_test = ['.*',]
#dbfilter_test = ['.*',]
show_debug = 1

View File

@ -0,0 +1,15 @@
[options]
xmlrpc_port = 8080
; This is the password that allows database operations:
; admin_passwd = admin
db_host = False
db_port = 5432
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons,dmi/run1
timezone = Europe/Brussels
#dbfilter_test = ['.*',]
show_debug = 1

View File

@ -8,7 +8,8 @@ db_port = 5433
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons,dev/dmi/run1
addons_path = ext/odoo/addons,ext/custom-addons,dmi/run1
timezone = Europe/Brussels
#dbfilter_test = ['.*',]
#dbfilter_test = ['.*',]
show_debug = 1

4556
dmi/run1/Kundendaten.ktr Normal file

File diff suppressed because it is too large Load Diff

4887
dmi/run1/Produktdaten.ktr Normal file

File diff suppressed because it is too large Load Diff

2305
dmi/run1/VAT-Lookup.ktr Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,5 +0,0 @@
/var/log/odoo/*.log {
copytruncate
missingok
notifempty
}

View File

@ -1,50 +0,0 @@
upstream odoo-server {
server 127.0.0.1:8069 fail_timeout=3000s;
}
server {
listen 80 default_server;
server_name _;
# Specifies the maximum accepted body size of a client request,
# as indicated by the request header Content-Length.
client_max_body_size 200m;
# log files
access_log /var/log/nginx/odoo-access.log;
error_log /var/log/nginx/odoo-error.log;
# increase proxy buffer to handle some OpenERP web requests
proxy_buffers 16 64k;
proxy_buffer_size 128k;
location / {
proxy_pass http://odoo-server;
# force timeouts if the backend dies
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_read_timeout 300s;
# set headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
# Let the OpenERP web service know that we're using HTTPS, otherwise
# it will generate URL using http:// and not https://
# proxy_set_header X-Forwarded-Proto https;
# by default, do not forward anything
proxy_redirect off;
}
# cache some static data in memory for 60mins.
# under heavy load this should relieve stress on the OpenERP web interface a bit.
location ~* /web/static/ {
proxy_cache_valid 200 60m;
proxy_buffering on;
expires 864000;
proxy_pass http://odoo-server;
}
}

View File

@ -10,15 +10,16 @@ db_user = False
debug_mode = False
list_db = True
log_level = error
logfile = /var/log/odoo/odoo-server.log
log_level = warn
#max_cron_threads = 1
#workers = 1
xmlrpc_interface = 127.0.0.1
# WILL BE OVERWRITTEN BY COMMAND LINE ARGS
xmlrpc_port = 8069
longpolling_port = 8072
logfile = /var/log/odoo/odoo-server.log
timezone = Europe/Brussels

View File

@ -27,11 +27,12 @@
'description': """Individuelle Anpassungen""",
'author': 'camadeus GmbH',
'website': 'http://www.camadeus.at',
'depends': ['crm','sale','mail','product','account'],
'depends': ['knowledge','crm','sale','mail','product','account'],
'data': [
'cam_custom_view.xml',
'cam_custom_data.xml',
'views/custom_theme.xml',
'security/ir.model.access.csv',
],
'installable': True,
'auto_install': False,

View File

@ -74,6 +74,38 @@
</field>
</field>
</record>
<!-- documents menu -->
<menuitem
name="Documents"
id="menu_document_main"
parent="knowledge.menu_document"
groups="base.group_document_user"
sequence="0"
/>
<record model="ir.actions.act_window" id="action_document_files">
<field name="name">Dokumente</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.attachment</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to create a new document.
</p><p>
The Documents repository gives you access to all attachments, such
as mails, project documents, invoices etc.
</p>
</field>
</record>
<menuitem
name="Documents"
action="action_document_files"
id="menu_document_files"
parent="menu_document_main"
sequence="0"
/>
</data>
</openerp>

View File

@ -0,0 +1,2 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"crm_opportunity_report_show","crm_opportunity_report_show","crm.model_crm_opportunity_report","base.group_sale_salesman",1,,,
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 crm_opportunity_report_show crm_opportunity_report_show crm.model_crm_opportunity_report base.group_sale_salesman 1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -26,6 +26,7 @@ from openerp.osv import fields, osv
from openerp import models, fields as f, api
import openerp.addons.decimal_precision as dp
from datetime import date, timedelta, datetime
from openerp.tools.translate import _
class account_payment_term(osv.osv):
_inherit = 'account.payment.term'
@ -81,7 +82,312 @@ class account_invoice(models.Model):
if inv.payment_term and inv.payment_term.skonto_tage:
inv.write({'skonto_faelligkeit': datetime.strptime(inv.date_invoice, '%Y-%m-%d') + timedelta(days=inv.payment_term.skonto_tage)})
return True
# Add context 'click_register_payment'
def invoice_pay_customer(self, cr, uid, ids, context=None):
if not ids: return []
dummy, view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_vendor_receipt_dialog_form')
inv = self.browse(cr, uid, ids[0], context=context)
return {
'name':_("Pay Invoice"),
'view_mode': 'form',
'view_id': view_id,
'view_type': 'form',
'res_model': 'account.voucher',
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context': {
'payment_expected_currency': inv.currency_id.id,
'default_partner_id': self.pool.get('res.partner')._find_accounting_partner(inv.partner_id).id,
'default_amount': inv.type in ('out_refund', 'in_refund') and -inv.residual or inv.residual,
'default_reference': inv.name,
'close_after_process': True,
'invoice_type': inv.type,
'invoice_id': inv.id,
'default_type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
'type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
'click_register_payment':True,
}
}
class account_voucher(osv.osv):
_inherit = 'account.voucher'
#Workaround to send context in _compute_writeoff_amount()
def onchange_line_ids(self, cr, uid, ids, line_dr_ids, line_cr_ids, amount, voucher_currency, type, context=None):
context = context or {}
if not line_dr_ids and not line_cr_ids:
return {'value':{'writeoff_amount': 0.0}}
line_osv = self.pool.get("account.voucher.line")
line_dr_ids = resolve_o2m_operations(cr, uid, line_osv, line_dr_ids, ['amount'], context)
line_cr_ids = resolve_o2m_operations(cr, uid, line_osv, line_cr_ids, ['amount'], context)
#compute the field is_multi_currency that is used to hide/display options linked to secondary currency on the voucher
is_multi_currency = False
#loop on the voucher lines to see if one of these has a secondary currency. If yes, we need to see the options
for voucher_line in line_dr_ids+line_cr_ids:
line_id = voucher_line.get('id') and self.pool.get('account.voucher.line').browse(cr, uid, voucher_line['id'], context=context).move_line_id.id or voucher_line.get('move_line_id')
if line_id and self.pool.get('account.move.line').browse(cr, uid, line_id, context=context).currency_id:
is_multi_currency = True
break
return {'value': {'writeoff_amount': self._compute_writeoff_amount(cr, uid, line_dr_ids, line_cr_ids, amount, type, context=context), 'is_multi_currency': is_multi_currency}}
def get_default_acc_id(self, cr, uid, args):
konto = self.pool.get('account.account').search(cr,uid,[('code','=','99999999')],limit=1)
if konto:
return konto[0]
else:
raise osv.except_osv(_('Konfigurationsfehler!'),_("Es ist kein Konto für den Ausgleich der Rechnungen definiert (Skonto). Bitte wenden Sie sich an den Support."))
return False
_defaults = {
'comment': 'Skonto',
'writeoff_acc_id': get_default_acc_id,
}
def _get_writeoff_amount(self, cr, uid, ids, name, args, context={}):
if not ids: return {}
currency_obj = self.pool.get('res.currency')
res = {}; diff_amount = 0.0
debit = credit = total_inv_residual = 0.0
for voucher in self.browse(cr, uid, ids, context=context):
sign = voucher.type == 'payment' and -1 or 1
for l in voucher.line_dr_ids:
debit += l.amount
if context.has_key('click_register_payment'):
if voucher.payment_option == 'with_writeoff':
# There can be several open lines => we only want to reconcile the line related to the invoice
if l.move_line_id and l.move_line_id.invoice and l.move_line_id.invoice.id == context.get('invoice_id',-1):
l.write({'reconcile': True, 'amount': l.amount_unreconciled})
total_inv_residual += (l.amount > 0 and l.amount_unreconciled - l.amount)
for l in voucher.line_cr_ids:
credit += l.amount
if context.has_key('click_register_payment'):
if voucher.payment_option == 'with_writeoff':
# There can be several open lines => we only want to reconcile the line related to the invoice
if l.move_line_id and l.move_line_id.invoice and l.move_line_id.invoice.id == context.get('invoice_id',-1):
l.write({'reconcile': True, 'amount': l.amount_unreconciled})
total_inv_residual += (l.amount > 0 and l.amount_unreconciled - l.amount)
currency = voucher.currency_id or voucher.company_id.currency_id
write_off_amount = voucher.amount - sign * (credit - debit)
if context.has_key('click_register_payment'):
write_off_amount = total_inv_residual * sign
res[voucher.id] = currency_obj.round(cr, uid, currency, write_off_amount)
return res
_columns = {
'writeoff_amount': fields.function(_get_writeoff_amount, string='Difference Amount', type='float', readonly=True, help="Computed as the difference between the amount stated in the voucher and the sum of allocation on the voucher lines."),
}
#working on context to differentiate the button clicks without affecting the present code
#Workaround to send context in _compute_writeoff_amount()
def _compute_writeoff_amount(self, cr, uid, line_dr_ids, line_cr_ids, amount, type, context={}):
debit = credit = total_inv_residual = 0.0
sign = type == 'payment' and -1 or 1
for l in line_dr_ids:
debit += l['amount']
#total_inv_residual += (l['amount'] > 0 and l['amount_unreconciled'] - l['amount'])
total_inv_residual += l['amount_unreconciled']
for l in line_cr_ids:
credit += l['amount']
#total_inv_residual += (l['amount'] > 0 and l['amount_unreconciled'] - l['amount'])
total_inv_residual += l['amount_unreconciled']
writeoff_amount = amount - sign * (credit - debit)
if context.has_key('click_register_payment'):
writeoff_amount = amount - (total_inv_residual)
return writeoff_amount
#Workaround to send context in _compute_writeoff_amount()
def recompute_voucher_lines(self, cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=None):
"""
Returns a dict that contains new values and context
@param partner_id: latest value from user input for field partner_id
@param args: other arguments
@param context: context arguments, like lang, time zone
@return: Returns a dict which contains new values, and context
"""
def _remove_noise_in_o2m():
"""if the line is partially reconciled, then we must pay attention to display it only once and
in the good o2m.
This function returns True if the line is considered as noise and should not be displayed
"""
if line.reconcile_partial_id:
if currency_id == line.currency_id.id:
if line.amount_residual_currency <= 0:
return True
else:
if line.amount_residual <= 0:
return True
return False
if context is None:
context = {}
context_multi_currency = context.copy()
currency_pool = self.pool.get('res.currency')
move_line_pool = self.pool.get('account.move.line')
partner_pool = self.pool.get('res.partner')
journal_pool = self.pool.get('account.journal')
line_pool = self.pool.get('account.voucher.line')
#set default values
default = {
'value': {'line_dr_ids': [], 'line_cr_ids': [], 'pre_line': False},
}
# drop existing lines
line_ids = ids and line_pool.search(cr, uid, [('voucher_id', '=', ids[0])])
for line in line_pool.browse(cr, uid, line_ids, context=context):
if line.type == 'cr':
default['value']['line_cr_ids'].append((2, line.id))
else:
default['value']['line_dr_ids'].append((2, line.id))
if not partner_id or not journal_id:
return default
journal = journal_pool.browse(cr, uid, journal_id, context=context)
partner = partner_pool.browse(cr, uid, partner_id, context=context)
currency_id = currency_id or journal.company_id.currency_id.id
total_credit = 0.0
total_debit = 0.0
account_type = None
if context.get('account_id'):
account_type = self.pool['account.account'].browse(cr, uid, context['account_id'], context=context).type
if ttype == 'payment':
if not account_type:
account_type = 'payable'
total_debit = price or 0.0
else:
total_credit = price or 0.0
if not account_type:
account_type = 'receivable'
if not context.get('move_line_ids', False):
if context.get('click_register_payment', False) and context.get('invoice_id', False):
ids = move_line_pool.search(cr, uid, [('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id', '=', partner_id),('invoice','=',context.get('invoice_id'))], context=context)
else:
ids = move_line_pool.search(cr, uid, [('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id', '=', partner_id)], context=context)
else:
ids = context['move_line_ids']
invoice_id = context.get('invoice_id', False)
company_currency = journal.company_id.currency_id.id
move_lines_found = []
#order the lines by most old first
ids.reverse()
account_move_lines = move_line_pool.browse(cr, uid, ids, context=context)
#compute the total debit/credit and look for a matching open amount or invoice
for line in account_move_lines:
if _remove_noise_in_o2m():
continue
if invoice_id:
if line.invoice.id == invoice_id:
#if the invoice linked to the voucher line is equal to the invoice_id in context
#then we assign the amount on that line, whatever the other voucher lines
move_lines_found.append(line.id)
elif currency_id == company_currency:
#otherwise treatments is the same but with other field names
if line.amount_residual == price:
#if the amount residual is equal the amount voucher, we assign it to that voucher
#line, whatever the other voucher lines
move_lines_found.append(line.id)
break
#otherwise we will split the voucher amount on each line (by most old first)
total_credit += line.credit or 0.0
total_debit += line.debit or 0.0
elif currency_id == line.currency_id.id:
if line.amount_residual_currency == price:
move_lines_found.append(line.id)
break
total_credit += line.credit and line.amount_currency or 0.0
total_debit += line.debit and line.amount_currency or 0.0
remaining_amount = price
#voucher line creation
for line in account_move_lines:
if _remove_noise_in_o2m():
continue
if line.currency_id and currency_id == line.currency_id.id:
amount_original = abs(line.amount_currency)
amount_unreconciled = abs(line.amount_residual_currency)
else:
#always use the amount booked in the company currency as the basis of the conversion into the voucher currency
amount_original = currency_pool.compute(cr, uid, company_currency, currency_id, line.credit or line.debit or 0.0, context=context_multi_currency)
amount_unreconciled = currency_pool.compute(cr, uid, company_currency, currency_id, abs(line.amount_residual), context=context_multi_currency)
line_currency_id = line.currency_id and line.currency_id.id or company_currency
rs = {
'name':line.move_id.name,
'type': line.credit and 'dr' or 'cr',
'move_line_id':line.id,
'account_id':line.account_id.id,
'amount_original': amount_original,
'amount': (line.id in move_lines_found) and min(abs(remaining_amount), amount_unreconciled) or 0.0,
'date_original':line.date,
'date_due':line.date_maturity,
'amount_unreconciled': amount_unreconciled,
'currency_id': line_currency_id,
}
remaining_amount -= rs['amount']
#in case a corresponding move_line hasn't been found, we now try to assign the voucher amount
#on existing invoices: we split voucher amount by most old first, but only for lines in the same currency
if not move_lines_found:
if currency_id == line_currency_id:
if line.credit:
amount = min(amount_unreconciled, abs(total_debit))
rs['amount'] = amount
total_debit -= amount
else:
amount = min(amount_unreconciled, abs(total_credit))
rs['amount'] = amount
total_credit -= amount
if rs['amount_unreconciled'] == rs['amount']:
rs['reconcile'] = True
if rs['type'] == 'cr':
default['value']['line_cr_ids'].append(rs)
else:
default['value']['line_dr_ids'].append(rs)
if len(default['value']['line_cr_ids']) > 0:
default['value']['pre_line'] = 1
elif len(default['value']['line_dr_ids']) > 0:
default['value']['pre_line'] = 1
default['value']['writeoff_amount'] = self._compute_writeoff_amount(cr, uid, default['value']['line_dr_ids'], default['value']['line_cr_ids'], price, ttype, context=context)
return default
def resolve_o2m_operations(cr, uid, target_osv, operations, fields, context):
results = []
for operation in operations:
result = None
if not isinstance(operation, (list, tuple)):
result = target_osv.read(cr, uid, operation, fields, context=context)
elif operation[0] == 0:
# may be necessary to check if all the fields are here and get the default values?
result = operation[2]
elif operation[0] == 1:
result = target_osv.read(cr, uid, operation[1], fields, context=context)
if not result: result = {}
result.update(operation[2])
elif operation[0] == 4:
result = target_osv.read(cr, uid, operation[1], fields, context=context)
if result != None:
results.append(result)
return results
class sale_order(osv.osv):
_inherit = 'sale.order'

View File

@ -34,5 +34,17 @@ action_number()
invoice_validate()
action_skonto_faelligkeit_assign()</field>
</record>
</data>
</data>
<data noupdate="1">
<record id="account_account_skonto" model="account.account">
<field name="name">Skonto</field>
<field name="code">99999999</field>
<field name="type">other</field>
<field name="user_type" search="[('code','=','other')]"/>
</record>
</data>
</openerp>

View File

@ -39,7 +39,7 @@
<group col="4">
<field name="skonto_tage"/>
<field name="netto_tage"/>
<field name="skonto_prozent"/>
<field name="skonto_prozent"/>
</group>
</xpath>
</field>
@ -54,10 +54,23 @@
<field name="skonto_faelligkeit"/>
</field>
<field name="residual" position="before">
<field name="skonto_betrag_inkl"/>
<field name="skonto_betrag_inkl" attrs="{'invisible': [('skonto_betrag_inkl','=',0)]}"/>
</field>
</field>
</record>
<!-- account.voucher -->
<record id="account_voucher_form" model="ir.ui.view">
<field name="name">cam_invoice_skonto.account_voucher.form</field>
<field name="model">account.voucher</field>
<field name="inherit_id" ref="account_voucher.view_vendor_receipt_dialog_form"/>
<field name="arch" type="xml">
<field name="writeoff_acc_id" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.form</field>

View File

@ -31,7 +31,7 @@ class res_company(osv.osv):
def get_image(self, img):
def _get_dir():
styles_dir = 'cam_custom/static/src/img'
styles_dir = 'cam_reports/static/src/img'
adps = addons.module.ad_paths
for adp in adps:
dir = os.path.join(adp, styles_dir)
@ -64,6 +64,23 @@ class res_company(osv.osv):
if os.path.isdir(dir):
break
if os.path.isdir(dir):
filename = os.path.join(dir, 'briefkopf.rml')
f = open(filename , 'rb')
data = f.read()
result = dict.fromkeys(ids, data)
return result
def _get_rml_header2(self, cr, uid, ids, _field_name, _args, context=None):
result = dict.fromkeys(ids, False)
# Get filename
dirname = 'cam_reports/report'
adps = addons.module.ad_paths
for adp in adps:
dir = os.path.join(adp, dirname)
if os.path.isdir(dir):
break
if os.path.isdir(dir):
filename = os.path.join(dir, 'page.rml')
f = open(filename , 'rb')
@ -72,5 +89,6 @@ class res_company(osv.osv):
return result
_columns = {
'rml_header': fields.function(_get_rml_header, type='text', string='RML Header'),
'rml_header': fields.function(_get_rml_header, type='text', string='Briefkopf',readonly=True),
'rml_header2': fields.function(_get_rml_header2, type='text', string='RML Header',readonly=True),
}

View File

@ -0,0 +1,99 @@
<header>
<pageTemplate>
<frame id="first" x1="1.5cm" y1="4cm" height="21.1cm" width="18.5cm"/>
<stylesheet>
<!-- Set here the default font to use for all <para> tags -->
<paraStyle name='Normal' fontName="Helvetica"/>
<paraStyle name="footer" fontName="Helvetica" leading="8" fontSize="7.0" alignment="LEFT"/>
<paraStyle name="footer_rechts" fontName="Helvetica" leading="8" fontSize="7.0" alignment="RIGHT"/>
<paraStyle name="header_fett" fontName="Helvetica-Bold" fontSize="7.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="header" fontName="Helvetica" fontSize="7.0" leading="8" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="Absender" fontName="Helvetica" fontSize="7.0" leading="8" alignment="LEFT" spaceAfter="0.0"/>
<paraStyle name="normal" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" />
<paraStyle name="fett" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT"/>
<paraStyle name="ueberschrift" fontName="Helvetica-Bold" fontSize="10.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
<paraStyle name="tabelle_header" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER"/>
<paraStyle name="tabelle_header_links" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT"/>
<paraStyle name="tabelle_header_rechts" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/>
<paraStyle name="tabelle_daten_center" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER"/>
<paraStyle name="tabelle_daten_links" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT"/>
<paraStyle name="tabelle_daten_links_italic" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" alignment="LEFT"/>
<paraStyle name="tabelle_daten_rechts" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT"/>
<paraStyle name="schlussrechnung" fontName="Helvetica" fontSize="9.0" leading="10" alignment="RIGHT"/>
<paraStyle name="schlussrechnung_fett" fontName="Helvetica-Bold" fontSize="9.0" leading="10" alignment="RIGHT"/>
<paraStyle name="skonto" fontName="Helvetica" fontSize="7.0" leading="10" alignment="RIGHT"/>
<!-- Tabellen -->
<blockTableStyle id="Struktur">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<blockTopPadding length="0"/>
<blockBottomPadding length="0"/>
<blockLeftPadding length="0"/>
<blockRightPadding length="0"/>
</blockTableStyle>
<blockTableStyle id="TabelleHaupt">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<lineStyle kind="LINEBELOW" colorName="#000000" thickness="0.5"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,0" thickness="1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="-1,-1" thickness="1"/>
</blockTableStyle>
<blockTableStyle id="TabelleSchlussrechnung">
<blockValign value="MIDDLE"/>
</blockTableStyle>
</stylesheet>
<pageGraphics>
<!-- Logo Oben 1 -->
<place x="1.75cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.partner_id.name ]]</para>
<para style="footer">[[ company.street ]]</para>
<para style="footer">[[ company.zip ]] [[ company.city ]]</para>
<para style="footer">[[ company.country_id.name ]]</para>
</place>
<!-- Logo Oben 2 -->
<place x="6.90cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">Telefon:</para>
<para style="footer">Telefax:</para>
<para style="footer">E-Mail:</para>
<para style="footer">Web:</para>
</place>
<place x="8.10cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.phone ]]</para>
<para style="footer">[[ company.fax ]]</para>
<para style="footer">[[ company.partner_id.email ]]</para>
<para style="footer">[[ company.partner_id.website ]]</para>
</place>
<!-- Logo Oben -->
<image x="13.80cm" y="26.60cm" height="1.5cm" preserveAspectRatio="1">[[ company.logo]]</image>
<!-- Seperator -->
<rect x="1.70cm" y="26.40cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Seperator -->
<rect x="1.70cm" y="1.85cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Footer links -->
<place x="1.75cm" y="0cm" height="1.75cm" width="18cm">
<para style="footer">Bankverbindung: BANK, IBAN: AT000000000000000000, BIC: AAAAAAAA</para>
<para style="footer">UID: [[company.vat ]], FN: [[ company.company_registry ]]</para>
<para style="footer">Die Ware bleibt bis zur vollständigen Bezahlung unser Eigentum.</para>
</place>
<!-- Seitenzahl -->
<setFont name="Helvetica" size="8"/>
<drawRightString x="561" y="58">Seite <pageNumber/> </drawRightString>
</pageGraphics>
</pageTemplate>
</header>

View File

@ -49,51 +49,5 @@
</blockTableStyle>
</stylesheet>
<pageGraphics>
<!-- Logo Oben 1 -->
<place x="1.75cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.partner_id.name ]]</para>
<para style="footer">[[ company.street ]]</para>
<para style="footer">[[ company.zip ]] [[ company.city ]]</para>
<para style="footer">[[ company.country_id.name ]]</para>
</place>
<!-- Logo Oben 2 -->
<place x="6.90cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">Telefon:</para>
<para style="footer">Telefax:</para>
<para style="footer">E-Mail:</para>
<para style="footer">Web:</para>
</place>
<place x="8.10cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.phone ]]</para>
<para style="footer">[[ company.fax ]]</para>
<para style="footer">[[ company.partner_id.email ]]</para>
<para style="footer">[[ company.partner_id.website ]]</para>
</place>
<!-- Logo Oben -->
<image x="13.80cm" y="26.60cm" height="1.5cm" preserveAspectRatio="1">[[ company.logo]]</image>
<!-- Seperator -->
<rect x="1.70cm" y="26.40cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Seperator -->
<rect x="1.70cm" y="1.85cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Footer links -->
<place x="1.75cm" y="0cm" height="1.75cm" width="18cm">
<para style="footer">Bankverbindung: BANK, IBAN: AT000000000000000000, BIC: AAAAAAAA</para>
<para style="footer">UID: [[company.vat ]], FN: [[ company.company_registry ]]</para>
<para style="footer">Die Ware bleibt bis zur vollständigen Bezahlung unser Eigentum.</para>
</place>
<!-- Seitenzahl -->
<setFont name="Helvetica" size="8"/>
<drawRightString x="561" y="58">Seite <pageNumber/> </drawRightString>
</pageGraphics>
</pageTemplate>
</header>

View File

@ -13,7 +13,7 @@
</para>
<para>[[repeatIn(objects,'o')]] [[ setLang(o.partner_id.commercial_partner_id.lang)]]</para>
<blockTable colWidths="270,85,145" style="Struktur">
<blockTable colWidths="270,230" style="Struktur">
<tr>
<td>
<section>
@ -25,28 +25,69 @@
<para style="normal">[[ (o.partner_id.state_id and o.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_id.country_id and o.partner_id.country_id.name) or '' ]]</para>
<!-- Für Sichtfenster -->
<section>[[ not (o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.ref) or removeParentNode('section') ]]
<para style="normal">&#160;</para>
</section>
</section>
<section>[[ (o.partner_shipping_id and o.partner_shipping_id.id != o.partner_id.id) or removeParentNode('section')]]
<spacer length="1.5cm"/>
<para style="normal">Lieferadresse:</para>
<para style="normal">[[ o.partner_shipping_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_shipping_id.commercial_partner_id.id != o.partner_shipping_id.id and o.partner_shipping_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_shipping_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_shipping_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_shipping_id.zip) or '' ]] [[ (o.partner_shipping_id and o.partner_shipping_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_shipping_id.state_id and o.partner_shipping_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_shipping_id.country_id and o.partner_shipping_id.country_id.name) or '' ]]</para>
</section>
</section>
<para></para>
</td>
<td>
<para style="normal">Angebotsdatum:[[ o.state not in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Bestelldatum:[[ o.state in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Quelldokument:</para>
<para style="normal">Referenz:</para>
<!--<para style="normal">Kundennummer:</para>-->
<para style="normal">Kunde UID Nr.:</para>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_order,date = True) ]]&#160;</para>
<para style="normal">[[ o.origin ]]&#160;</para>
<para style="normal">[[ o.client_order_ref ]]&#160;</para>
<!--<para style="normal">[[ o.partner_id.commercial_partner_id.ref ]]&#160;</para>-->
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]&#160;</para>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]&#160;</para>
<blockTable colWidths="85,145" style="Struktur">
<tr>
<td>
<para style="normal">Angebotsdatum:[[ o.state not in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Bestelldatum:[[ o.state in ['draft','sent'] and removeParentNode('para') ]]</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_order,date = True) ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Quelldokument:[[ o.state not in ['draft','sent'] and removeParentNode('tr') ]]</para>
</td>
<td>
<para style="normal">[[ o.origin ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Kundennummer:</para>
</td>
<td>
<para style="normal">[[ o.client_order_ref ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Kunde UID Nr.:</para>
</td>
<td>
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]</para>
</td>
</tr>
</blockTable>
</td>
</tr>
<!--

View File

@ -1,41 +1,24 @@
# -*- coding: utf-8 -*-
import ast
import base64
import csv
import glob
import itertools
import logging
import operator
import datetime
import hashlib
import os
import re
import simplejson
import time
import urllib
import urllib2
import urlparse
import xmlrpclib
import zlib
from xml.etree import ElementTree
from cStringIO import StringIO
import babel.messages.pofile
import werkzeug.utils
import werkzeug.wrappers
try:
import xlwt
except ImportError:
xlwt = None
import openerp
import openerp.modules.registry
from openerp.tools.translate import _
from openerp.tools import config
from openerp.addons.web import http
from openerp.addons.web.controllers.main import Home
from openerp.http import request
class Home_Debug(Home):
@http.route('/', type='http', auth="none")
def index(self, s_action=None, db=None, **kw):
# Check arguments
if openerp.tools.config.get('show_debug', False):
return http.local_redirect('/web?debug=1', query=request.params, keep_hash=True)
else:
return http.local_redirect('/web', query=request.params, keep_hash=True)
class WebClient(http.Controller):
_cp_path = "/web/testenv"

View File

@ -0,0 +1,13 @@
--- ext/odoo/odoo-dev.py 2015-04-08 10:11:02.000000000 +0200
+++ ext/odoo/odoo-dev.py 2015-04-08 10:11:02.000000000 +0200
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import sys
+if sys.modules.get("gevent") is not None:
+ del sys.modules['gevent']
+import openerp
+
+if __name__ == "__main__":
+ openerp.cli.main()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,11 @@
--- ext/odoo/openerp/report/report_sxw.py 2015-04-15 12:18:30.132784074 +0200
+++ ext/odoo/openerp/report/report_sxw.py 2015-04-15 11:48:21.743518606 +0200
@@ -476,6 +476,8 @@
processed_rml = etree.XML(rml)
if report_xml.use_global_header:
rml_parser._add_header(processed_rml, self.header)
+ else:
+ rml_parser._add_header(processed_rml, 'internal')
processed_rml = self.preprocess_rml(processed_rml,report_xml.report_type)
if rml_parser.logo:
logo = base64.decodestring(rml_parser.logo)

1
setup/ir.translation.csv Normal file
View File

@ -0,0 +1 @@
lang,type,name,res_id,src,value
1 lang type name res_id src value

View File

@ -52,7 +52,9 @@ def main():
'set_warehouse',
'base_config',
'sale_config',
'hr_config',
'stock_config',
'stock_set_cost_method',
'set_incoterms',
'purchase_config',
'set_date_format',
@ -63,6 +65,11 @@ def main():
'setup_journals',
'set_currencies',
'set_decimal_price',
'set_default_values',
'set_translations',
'set_default_removal_strategy',
'default_set_order_policy',
]
if cmd == 'rollout':
@ -71,6 +78,8 @@ def main():
'set_dokumentennummern',
'set_dmi_noupdate',
'dmi_confirm_inventory',
'setup_mail_server',
'import_users',
]
if cmd == 'update':

View File

@ -8,7 +8,8 @@ class Config():
self.sales_tax = '20% MwSt'
self.purchase_tax = '20% VSt'
self.chart_template_id = 2 # Austrian Chart of Account
self.digits = 2 #Nachkommastellen Preis
self.price_decimals = 2 # Nachkommastellen Preis
self.uom_decimals = 3 # Nachkommastellen Mengeneinheiten
self.company_data = {
'name': 'Camadeus GmbH',
@ -20,15 +21,24 @@ class Config():
'fax': False,
'email': 'office@camadeus.at',
'website': 'http://www.camadeus.at',
'company_registry': '280076b ',
'company_registry': '280076b',
'country_id': 'at', # "de" für deutschland
'logo': False,
'vat': 'ATU 62991855 ',
'vat': 'ATU 62991855',
'rml_header1': False,
'vat_check_vies': True,
'tax_calculation_rounding_method': 'round_globally',
#'rml_header' : './ext/addons/custom_reports/report/page.rml', # Report File
'logo': '../ext/custom-addons/cam_reports/logo.png',
'logo': '../ext/custom-addons/cam_custom/static/src/img/logo.png',
}
self.mail_server = {
'name': 'test',
'sequence': 0,
'smtp_host': 'smtp.1und1.de',
'smtp_port': '465',
'smtp_encryption': 'ssl',
'smtp_user': 'test',
'smtp_pass': 'test',
}
# Nur für Lager
@ -47,7 +57,6 @@ class Config():
#'Lieferant EU (ohne Ust-ID)',
#'Lieferant EU Unternehmen (mit USt-ID)',
#'Lieferant Ausland',
#'Kunde EU (ohne USt-ID)',
'Kunde Ausland',
'Kunde EU (ohne USt-ID)',
'Kunde EU Unternehmen (mit USt-ID)',
@ -61,6 +70,7 @@ class Config():
# Allgemeine Einstellungen
self.base_config = {
'module_portal': False, # Kundenportal
'alias_domain': False, # False: keine Domainbezogenen E-Mails (wie zB. Reply-To zur alias-Adresse)
}
# Einstellungen Verkauf
@ -69,20 +79,38 @@ class Config():
'group_sale_pricelist': True, # Preislisten verwenden
'group_discount_per_so_line': True, # Rabatte verwenden
'group_uom': True, # Verwende Mengeneinheiten
'group_invoice_deli_orders': True, # Erstelle Rechnungen durch Auslieferungen
}
self.order_policy = 'picking' # Erzeuge Rechnung: [manual], [picking],[prepaid]
# Einstellungen Einkauf
self.purchase_config = {
'group_purchase_pricelist': True, # Preislisten verwenden
'default_invoice_method': 'manual', # [picking] - Rechnung von Lieferscheinen
# [manual] - von Bestellpositionen
# [order] - Vorabrechnungsentwurf durch Bestellung
'group_costing_method': True, # Benutzen Sie 'Einkaufs-' oder 'Durchschnittspreis' zur Bestandsbewertung
}
#Einstellungen Personal
self.hr_config = {
'module_hr_expense': True, # Spesen der Mitarbeiter verwalten
'module_hr_timesheet': False, # Verwalten Sie Ihre Studenzettel
'group_hr_attendance': True, # Zuweisung der Berechtigung zur Arbeitszeiteingabe für alle Benutzer
}
#Einstellungen Lager
self.stock_config = {
'group_stock_multiple_locations': True, # Verwalten Sie mehrere Läger und Lagerorte
'group_stock_multiple_locations': True, # Verwalten Sie mehrere Lager und Lagerorte
'group_stock_tracking_lot': False, # Benutze Verpackungen: Paletten, Boxen, ...
'group_stock_packaging': False, # Ermöglicht die Auswahl einer Verpackung
}
self.removal_strategy = 'fefo' #[fifo], [lifo], [fefo]
self.stock_cost_method = 'average' # [standard], [average], [real]
# Wenn gesetzt, teilen sich Gutschriften und Rechnungen den selben Nummernkreis
self.refund_invoice_sequence = True
@ -143,6 +171,7 @@ class Config():
self.modules = [
'document',
'knowledge',
'auth_crypt',
'cam_testenv',
'cam_max_width',
@ -152,10 +181,20 @@ class Config():
'account_cancel',
'cam_invoice_skonto',
'web_printscreen_zb',
#'crm',
#'sale',
'crm',
'sale',
#'cam_hr_overtime',
#'cam_hr',
#'sale_order_optiona',
#'sale_order_reminder',
]
self.users_file = "res.users.csv"
self.translation_files = [
"ir.translation.csv"
]
self.default_values = [ # ir.values
#('product.template', 'type', 'service'),
]

View File

@ -23,7 +23,8 @@ Port: %s
ENVIRONMENTS = {
'br': Environment('http://localhost', '8080', 'INSTANCE_1', 'admin', 'x', 'admin'),
'sk': Environment('http://localhost', '8080', 'INSTANCE_1', 'admin', 'x', 'admin'),
'test': Environment('https://test1.camadeus.at', '443', 'INSTANCE_1', 'admin', 'x', 'asdfasdf'),
'sk': Environment('http://localhost', '8080', 'INSTANCE_1', 'admin', 'x', 'admin'),
'ka': Environment('http://localhost', '8080', 'INSTANCE_1', 'admin', 'x', 'admin'),
'test': Environment('https://INSTANCE.camadeus.at', '443', 'INSTANCE_1', 'admin', '141kcal', 'asdfasdf'),
}

View File

@ -149,6 +149,16 @@ class CamadeusFunctions():
wizard_id = self._execute('stock.config.settings', 'create', vals)
return self._execute('stock.config.settings', 'execute', [wizard_id])
return True
def hr_config(self):
"""Basiskonfiguration für Personal Laden"""
if hasattr(self.config, 'hr_config'):
vals = self._execute('hr.config.settings', 'default_get', [])
vals.update(self.config.hr_config)
wizard_id = self._execute('hr.config.settings', 'create', vals)
return self._execute('hr.config.settings', 'execute', [wizard_id])
return True
def set_incoterms(self):
"""Lieferbedingungen setzen"""
@ -501,11 +511,131 @@ class CamadeusFunctions():
return True
def set_decimal_price(self):
"""Dezimalstellen Preis setzen"""
"""Dezimalstellen 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})
# UOM
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_product_uom')
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.uom_decimals})
if not res:
return False
# UOS
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_product_uos')
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.uom_decimals})
if not res:
return False
# Product Price
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_price')
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.price_decimals})
if not res:
return False
# Product Price
ids = self._execute('decimal.precision', 'search', [('name','=','Product Price')])
res = self._execute('decimal.precision', 'write', ids, {'digits': self.config.price_decimals})
if not res:
return False
return True
def setup_mail_server(self):
"""Mailserver einrichten"""
if hasattr(self.config, 'mail_server'):
vals = self.config.mail_server
server_ids = self._execute('ir.mail_server', 'search', [('name','=',vals.get('name'))])
if server_ids:
return self._execute('ir.mail_server', 'write', server_ids, vals)
else:
return self._execute('ir.mail_server', 'create', vals)
return False
def stock_set_cost_method(self):
"""Kalkulationsverfahren für Lager setzen"""
if hasattr(self.config, 'stock_cost_method'):
method = self.config.stock_cost_method
self._execute('ir.values', 'set_default', 'product.template', 'cost_method', method)
return True
return True
def import_users(self):
"""User importieren"""
if hasattr(self.config, 'users_file'):
vals = {}
vals['res_model'] = 'res.users'
vals['file'] = self._readAndReturnFile(self.config.users_file)
fields = [u'id', u'name', u'login', u'email', u'groups_id/id', False, u'tz', u'mobile', u'phone', u'function']
options = {u'headers': True, u'quoting': u'"', u'separator': u',', u'encoding': u'utf-8'}
wizard_id = self._execute('base_import.import', 'create', vals)
if wizard_id:
messages = self._execute('base_import.import', 'do',wizard_id,fields,options)
if messages:
print messages
return False
return True
return False
def set_translations(self):
"""Übersetzungen aktualisieren """
if hasattr(self.config, 'translation_files'):
for file in self.config.translation_files:
data = self._readAndReturnFile(file,encode='base64')
vals = {
'name': 'test',
'code': 'de_DE',
'data': data,
'overwrite': True,
}
wizard_id = self._execute('base.language.import', 'create', vals)
self._execute('base.language.import', 'import_lang', [wizard_id])
return True
return False
def default_set_order_policy(self):
"""Setze Rechnung von Lieferschein"""
if hasattr(self.config, 'order_policy'):
method = self.config.order_policy
self._execute('ir.values', 'set_default', 'sale.order', 'order_policy', method)
return True
def set_default_removal_strategy(self):
"""Default Entnahmestrategie für Lager setzen"""
if hasattr(self.config, 'removal_strategy'):
method = self.config.removal_strategy
strategy_ids = self._execute('product.removal', 'search', [('method','=',method)])
if not strategy_ids:
return False
stock_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'stock.stock_location_stock')
if not stock_id:
return False
return self._execute('stock.location', 'write', stock_id,{'removal_strategy_id':strategy_ids[0]})
return False
def set_default_values(self):
"""Defaultwerte für Dokumente setzen"""
for model,field,value in self.config.default_values:
vals = {
'name': field,
'model': model,
'value_unpickle': value,
'key': 'default',
'key2': False,
}
domain = [('name','=',field),('model','=',model)]
val_ids = self._execute('ir.values', 'search', domain)
if val_ids:
self._execute('ir.values', 'write', val_ids, vals)
else:
self._execute('ir.values', 'create', vals)
return True

View File

@ -0,0 +1,399 @@
# Agent: sudo puppet agent --test
class odoo {
user { odoo:
ensure => present,
shell => '/bin/bash',
managehome => 'true',
}
$sudo_entry="odoo ALL=NOPASSWD: ALL"
sudo::conf { 'sudo_odoo':
priority => 10,
content => $sudo_entry,
}
ssh_authorized_key { "andreas@odoo":
user => odoo,
type => 'ssh-rsa',
#key => 'AAAAB3NzaC1yc2EAAAABIwAAAQEAtd8TfqMUhFXsHuWHL0NBPem5V4eLdG4SKe2xTfIMFL7xGGvXjox7BDncUVJ/MSnYS5aWRYEjz1QY80Kj6KIpxqh8imW2EscLKHzMfcOEwzQh+7lcC/nexMrjlPOS2LyAh3KHTqUKbdxq4a6KuGqoydIY6u/pRBDgEAh5y0/YLJwIjTIDmW/lTB6ZlcXIMPTY05QsPG/adL76rN2TowG8qvP45uLoH9EjZ//9nes3lyjegsia2uJ4mVlvA3vEpzRC2Ku2F69ADUV7SVOyzvOvPi6l/RpbXHYJO5XWxyn2NrxZWPGuUCF5+JL3KYElIBTTTTB3gDWzWQAVF/QKXi1eiw==',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDBIg6NZV4tTs+J5qUP4/zQAn+Xi3muKqbaSDV8yYm50mH77PcLwbkZVlxdF0/OFCl5f5FCNp4Ag4Px97M35Nv+BweOTCZNMKOHmvtXY1fCRUQnk6ca3NlipImppL0U47SUzt9KkNIsz0FWxLu74LANgxKwrf8Hgim8Nkq8WrlvuoJCqf+542N15cGrf/9eD6yRm7AmdFi7VIYrP4m7TPbXJBGX+cXOo0bKTyaq8mtinbUN5UCi/eJ08wYkm/CGVxL+9cm6HOABw332A8OadAliCZBWqhFT0rBKdoWLxBbTsILALskrddpKLwBLOUIU79YeT0OfNpLCnVi8u67X9inl',
}
ssh_authorized_key { "stefan@odoo":
user => odoo,
type => 'ssh-rsa',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDlOWE1x6FF4VsHTRSZ31iQsASlRLqMdIhyIY52ENM46uTOTEOENiyeFrQkRKZfIsic3TBg+u7HedzsCRl4U9Cy9boX46bkeFi1qZFB3iHkcIFDrlqQo0OBIlidNkuQ8fiDVVhjSJGzwRRiwIRp5f7vkBuYAhLMqgOXESXUhKl9RZFYaTAW4fEAQ1rqVAKibwiPaNpwh0zj4GeX8Ab2+NBNfKt8MslvEEbNbUCViH6ZS7DR66p+gYWTtP+Rzyd1F92pmoHam7Lqsk4Qc+5G7HHzDJuidsiu5UQiVaPu2KhzuX7fKEnRC0vDkknwuyYf7hUeuK8j0GpDpDmfWmo36Cyz',
}
ssh_authorized_key { "kumar@odoo":
user => odoo,
type => 'ssh-rsa',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDA8tPgqD6ZRixJGGypzKgeVUGnK5mGVfT25qQYFChTsjXVeCgfCNnN7IfnN8H7ive+du9Cz/G10hsH4v/1HZ8w0KaEWieWyiBjWDIoOJIdw3mjeLA2G0HR7aZ1Kal0VMh1zteGiHKBro7ASMEn58OVOKzxrGK0s/dTiZ/pAu0yyoD9CDvqAfhhJm+EAh2E9/CG3QfhndSkHZen/AYxhIek1Wv5RwRneKns5iDs/MJyjC9VFuZCVyYHIzshzHtHkAH7O1hxd++pKuvNiI8w0CoeTr+DwpwZRMEpsohIygyRkEgYgVQlGyxf7chHy6Mip91ljzHKNCAVG5VDNtY7ij5P',
}
class { 'postgresql::server':
listen_addresses => '*',
locale => 'de_AT.UTF-8',
encoding => 'UTF8',
}
# workaround for http://projects.puppetlabs.com/issues/4695
# when PostgreSQL is installed with SQL_ASCII encoding instead of UTF8
exec { 'utf8 postgres':
command => 'sudo -u postgres pg_dropcluster --stop 9.1 main ; pg_createcluster --start --locale en_US.UTF-8 9.1 main',
unless => 'sudo -u postgres psql -t -c "\l" | grep template1 | grep -q UTF',
require => Class['postgresql::server'],
path => ['/bin', '/sbin', '/usr/bin', '/usr/sbin'],
}
file { "/var/log/odoo":
owner => 'root',
group => 'root',
mode => '0777',
ensure => "directory",
}
package { ['antiword',
'bzr',
'git',
'nginx',
'poppler-utils',
'postgresql',
'python-dateutil',
'python-decorator',
'python-docutils',
'python-egenix-mxdatetime',
'python-feedparser',
'python-gevent',
'python-imaging',
'python-jinja2',
'python-ldap',
'python-libxslt1',
'python-lxml',
'python-mako',
'python-matplotlib',
'python-mock',
'python-openid',
'python-openssl',
'python-paramiko',
'python-pdftools',
'python-pip',
'python-psutil',
'python-psycopg2',
'python-pybabel',
'python-pychart',
'python-pydot',
'python-pyparsing',
'python-pypdf',
'python-reportlab-accel',
'python-reportlab',
# 'python-requests', ist bei debian version 0.12.1 => daher install mit pip
'python-setuptools',
'python-simplejson',
'python-tz',
'python-unittest2',
'python-vatnumber',
'python-vobject',
'python-webdav',
'python-werkzeug',
'python-xlwt',
'python-yaml',
'python-zsi',
'wget',
# für wkhtmltox
'xfonts-base',
'xfonts-75dpi',
]:
ensure => present,
}
file { 'wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb':
name => "/tmp/wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb",
owner => root,
group => root,
source => "puppet:///modules/odoo/wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb"
}
package { 'wkhtmltox':
provider => dpkg,
ensure => installed,
source => "/tmp/wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb",
require => [File['wkhtmltox-0.12.2.1_linux-wheezy-amd64.deb'],Package['xfonts-base']],
}
package {['passlib',
'psycogreen',
'gdata',
'requests']:
ensure => installed,
provider => 'pip',
require => Package['python-pip'],
}
# Update python lib distribute if required ("sudo easy_install -U distribute")
$upg_cmd = "sudo easy_install -U distribute"
$unless_upg_cmd = "sudo pip freeze | grep distribute==0.7"
exec { 'upgrade_distribute':
command => $upg_cmd,
unless => $unless_upg_cmd,
path => ['/bin', '/sbin', '/usr/bin', '/usr/sbin'],
}
# TODO, benötigt: "sudo easy_install -U distribute"
package {'gevent_psycopg2':
ensure => present,
provider => 'pip',
require => [Package['python-pip'],Package['python-psycopg2'],Exec['upgrade_distribute'], Class['postgresql::server']],
}
# main directory for odoo backups
file { "/var/pgdump":
owner => 'root',
group => 'root',
mode => '0777',
ensure => "directory",
}
# Postfix setup
class { '::postfix::server':
myhostname => 'test.camadeus.at',
mydomain => 'camadeus.at',
mydestination => "\$myhostname, localhost.\$mydomain, localhost, $fqdn",
inet_interfaces => 'localhost',
}
# Default nginx file (prevent default server) REQUIRES SSL-key!!!
# Conf file
file { "/etc/nginx/conf.d/default.conf":
owner => 'www-data',
group => 'www-data',
mode => '0600',
ensure => present,
content => template('odoo/default.nginx.erb'),
notify => Package['nginx'],
}
}
define odoo::instance ($db_pw,$ssl = false, $servername, $odooport, $odooport_longpolling) {
$instance = $title
include odoo
user {$instance:
ensure => present,
groups => ["sudo"],
shell => '/bin/bash',
managehome => 'true',
}
$key_andreas="andreas@$instance"
ssh_authorized_key { $key_andreas:
user => $instance,
type => 'ssh-rsa',
#key => 'AAAAB3NzaC1yc2EAAAABIwAAAQEAtd8TfqMUhFXsHuWHL0NBPem5V4eLdG4SKe2xTfIMFL7xGGvXjox7BDncUVJ/MSnYS5aWRYEjz1QY80Kj6KIpxqh8imW2EscLKHzMfcOEwzQh+7lcC/nexMrjlPOS2LyAh3KHTqUKbdxq4a6KuGqoydIY6u/pRBDgEAh5y0/YLJwIjTIDmW/lTB6ZlcXIMPTY05QsPG/adL76rN2TowG8qvP45uLoH9EjZ//9nes3lyjegsia2uJ4mVlvA3vEpzRC2Ku2F69ADUV7SVOyzvOvPi6l/RpbXHYJO5XWxyn2NrxZWPGuUCF5+JL3KYElIBTTTTB3gDWzWQAVF/QKXi1eiw==',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDBIg6NZV4tTs+J5qUP4/zQAn+Xi3muKqbaSDV8yYm50mH77PcLwbkZVlxdF0/OFCl5f5FCNp4Ag4Px97M35Nv+BweOTCZNMKOHmvtXY1fCRUQnk6ca3NlipImppL0U47SUzt9KkNIsz0FWxLu74LANgxKwrf8Hgim8Nkq8WrlvuoJCqf+542N15cGrf/9eD6yRm7AmdFi7VIYrP4m7TPbXJBGX+cXOo0bKTyaq8mtinbUN5UCi/eJ08wYkm/CGVxL+9cm6HOABw332A8OadAliCZBWqhFT0rBKdoWLxBbTsILALskrddpKLwBLOUIU79YeT0OfNpLCnVi8u67X9inl',
}
$key_stefan="stefan@$instance"
ssh_authorized_key { $key_stefan:
user => $instance,
type => 'ssh-rsa',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDlOWE1x6FF4VsHTRSZ31iQsASlRLqMdIhyIY52ENM46uTOTEOENiyeFrQkRKZfIsic3TBg+u7HedzsCRl4U9Cy9boX46bkeFi1qZFB3iHkcIFDrlqQo0OBIlidNkuQ8fiDVVhjSJGzwRRiwIRp5f7vkBuYAhLMqgOXESXUhKl9RZFYaTAW4fEAQ1rqVAKibwiPaNpwh0zj4GeX8Ab2+NBNfKt8MslvEEbNbUCViH6ZS7DR66p+gYWTtP+Rzyd1F92pmoHam7Lqsk4Qc+5G7HHzDJuidsiu5UQiVaPu2KhzuX7fKEnRC0vDkknwuyYf7hUeuK8j0GpDpDmfWmo36Cyz',
}
$key_kumar="kumar@$instance"
ssh_authorized_key { $key_kumar:
user => $instance,
type => 'ssh-rsa',
key => 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDA8tPgqD6ZRixJGGypzKgeVUGnK5mGVfT25qQYFChTsjXVeCgfCNnN7IfnN8H7ive+du9Cz/G10hsH4v/1HZ8w0KaEWieWyiBjWDIoOJIdw3mjeLA2G0HR7aZ1Kal0VMh1zteGiHKBro7ASMEn58OVOKzxrGK0s/dTiZ/pAu0yyoD9CDvqAfhhJm+EAh2E9/CG3QfhndSkHZen/AYxhIek1Wv5RwRneKns5iDs/MJyjC9VFuZCVyYHIzshzHtHkAH7O1hxd++pKuvNiI8w0CoeTr+DwpwZRMEpsohIygyRkEgYgVQlGyxf7chHy6Mip91ljzHKNCAVG5VDNtY7ij5P',
}
$sudo_entry="$instance ALL = (root) NOPASSWD: /etc/init.d/odoo-server-$instance, /usr/sbin/service odoo-server-$instance *"
sudo::conf { $instance:
priority => 10,
content => $sudo_entry,
}
# Logfile
file { "/var/log/odoo/$instance":
owner => $instance,
group => $instance,
mode => '0700',
ensure => "directory",
#require => file['/var/log/odoo'],
}
file { "/home/$instance/logs":
ensure => "link",
owner => $instance,
group => $instance,
mode => '0600',
target => "/var/log/odoo/$instance/odoo-server.log",
}
$require_log = "file[/var/log/odoo/$instance]"
file { "/var/log/odoo/$instance/odoo-server.log":
owner => $instance,
group => $instance,
mode => '0600',
ensure => present,
require => $require_log,
}
$logrotate_file = "/etc/logrotate.d/odoo-$instance"
file { $logrotate_file:
owner => 'root',
group => 'root',
mode => '0644',
ensure => present,
content => template('odoo/logrotate.erb'),
}
# init file
# sudo ln -s /opt/odoo/odoo/config/odoo-server.init /etc/init.d/odoo-server
$init_odoo_notify = "Service[odoo-server-$instance]"
file { "/etc/init.d/odoo-server-$instance":
owner => $instance,
group => $instance,
mode => '0755',
ensure => present,
content => template('odoo/odoo-server.init.erb'),
notify => $init_odoo_notify,
}
file { "/home/$instance/restart.sh":
owner => $instance,
group => $instance,
mode => '0755',
ensure => present,
content => template('odoo/restart.sh.erb'),
}
file { "/home/$instance/ext.git":
owner => $instance,
group => $instance,
mode => '0600',
ensure => "directory",
recurse => true,
require => Package[git],
}
file { "/home/$instance/ext":
owner => $instance,
group => $instance,
mode => '0700',
ensure => "directory",
}
$git_requires = "File[/home/$instance/ext.git]"
$git_create_cmd = "sudo -u $instance git init --bare /home/$instance/ext.git"
$git_unless_cmd = "sudo -u $instance test -e /home/$instance/ext.git/HEAD"
$git_repo = "git_repo_$instance"
exec { $git_repo:
command => $git_create_cmd,
unless => $git_unless_cmd,
path => ['/bin', '/sbin', '/usr/bin', '/usr/sbin'],
require => $git_requires,
}
file { "/home/$instance/ext.git/hooks/post-receive":
owner => $instance,
group => $instance,
mode => '0700',
ensure => present,
content => "#!/bin/bash
git --work-tree=/home/$instance/ext --git-dir=/home/$instance/ext.git checkout -f",
require => Exec[$git_repo],
}
# backup
file { "/home/$instance/odoo-backup.sh":
owner => $instance,
group => $instance,
mode => '0700',
ensure => present,
content => template('odoo/odoo-backup.sh.erb'),
}
$cron_cmd = "/home/$instance/odoo-backup.sh"
$cron_require = "file[/home/$instance/odoo-backup.sh]"
$odoo_backup = "odoo-backup-$instance"
cron { $odoo_backup:
command => $cron_cmd,
user => $instance,
hour => 1,
minute => 30,
require => $cron_require,
}
# dictionaly for odoo backups
file { "/var/pgdump/$instance":
owner => $instance,
group => $instance,
mode => '0700',
ensure => "directory",
}
$odoo_service = "odoo-server-$instance"
$odoo_service_req = "file[/etc/init.d/odoo-server-$instance]"
# Run server
service {$odoo_service:
ensure => running,
require => $odoo_service_req,
enable => true,
}
# Postgresql User
# sudo su - postgres -c "createuser -s $OE_USER" 2> /dev/null || true
postgresql::server::role { "$instance":
password_hash => postgresql_password($instance, $db_pw),
createdb => true,
require => Exec['utf8 postgres'],
}
# NGINX
# Run server
service {'nginx':
ensure => running,
require => Package['nginx'],
enable => true,
}
if str2bool("$ssl") {
$key_file_test = "test -e /etc/nginx/ssl/$instance.key"
$key_file_cmd = "sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/nginx/ssl/$instance.key -out /etc/nginx/ssl/$instance.crt -subj \"/C=AT/ST=Vienna/L=Vienna/O= Security/OU=IT Department/CN=dummy\""
$certname = "ssl_cert_$instance"
exec { $certname:
command => $key_file_cmd,
unless => $key_file_test,
path => ['/bin', '/sbin', '/usr/bin', '/usr/sbin'],
notify => Service['nginx'],
require => Package[nginx],
}
}
# Conf file
file { "/etc/nginx/conf.d/odoo-$instance.conf":
owner => 'www-data',
group => 'www-data',
mode => '0600',
ensure => present,
content => template('odoo/odoo.nginx.erb'),
require => Package[nginx],
notify => Service['nginx'],
}
}

View File

@ -0,0 +1,19 @@
server {
listen 80 default_server;
return 444;
server_name _;
}
#server {
# listen 443 ssl default_server;
# return 444;
# server_name _;
# THIS IS REQUIRED FOR SSL!!!!
#ssl_certificate /etc/nginx/ssl/camadeus.at.crt;
#ssl_certificate_key /etc/nginx/ssl/camadeus.at.key;
#ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers HIGH:!aNULL:!MD5;
#}

View File

@ -0,0 +1,7 @@
/var/log/odoo/<%= @instance %>/*.log {
copytruncate
missingok
notifempty
size 5M
rotate 10
}

View File

@ -5,14 +5,14 @@
hostname=`/bin/hostname`
dbnames=`psql -d postgres -c "SELECT datname FROM pg_database WHERE NOT datistemplate AND datname <> 'postgres'" --tuples-only`
dbnames=`psql -d postgres -c "SELECT datname FROM pg_database WHERE NOT datistemplate AND datname <> 'postgres' AND datname like '<%= @instance %>%'" --tuples-only`
# Dump DBs
for db in $dbnames
do
echo "creating backup for db: " $db
date=`date +"%Y%m%d_%H%M%N"`
filename="/var/pgdump/${hostname}_${db}_${date}.sql"
filename="/var/pgdump/<%= @instance %>/${hostname}_${db}_${date}.sql"
pg_dump -E UTF-8 -F p -b -f $filename $db
chmod 600 $filename
gzip $filename
@ -22,7 +22,7 @@ done
##########################################
## Housekeeping
##########################################
for file in `find /var/pgdump/ -mtime +30 -type f -name '*.sql.gz'`
for file in `find /var/pgdump/<%= @instance %> -mtime +30 -type f -name '*.sql.gz'`
do
echo "deleting: " $file
rm $file

View File

@ -0,0 +1,36 @@
[options]
addons_path = /opt/odoo/ext/odoo/addons,/opt/odoo/ext/custom-addons
admin_passwd = <%= @master_pw %>
db_host = False
db_name = False
db_password = False
db_port = False
db_user = odoo
debug_mode = False
list_db = True
log_level = error
logfile = /var/log/odoo/<%= @master_pw %>/odoo-server.log
max_cron_threads = 1
workers = 1
#xmlrpc_interface = 127.0.0.1
xmlrpc_port = 8069
timezone = Europe/Brussels
# 5 min
#limit_time_cpu = 300
# 10 min
#limit_time_real = 600
# input DMI:
limit_time_cpu = 3000
limit_time_real = 6000
# if DB > 150MB, otherwise "AccessDenied" error occurs
# 10 GB
limit_memory_hard = 10000000000

View File

@ -1,7 +1,7 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: odoo-server
# Provides: odoo-server-<%= @instance %>
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network
@ -13,22 +13,23 @@
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/local/bin
DAEMON=/opt/odoo/odoo/openerp-server
NAME=odoo-server
DESC=odoo-server
DAEMON=/home/<%= @instance %>/ext/ext/odoo/odoo.py
NAME=odoo-server-<%= @instance %>
DESC=odoo-server-<%= @instance %>
WORKING_DIR=/home/<%= @instance %>/ext/ext/odoo
#FILTER="^%d$"
FILTER="^<%= @instance %>"
# Specify the user name (Default: openerp).
USER=odoo
USER=<%= @instance %>
# Specify an alternate config file (Default: /etc/openerp-server.conf).
CONFIGFILE="/opt/odoo/ext/config/odoo-server.conf"
CONFIGFILE="/home/<%= @instance %>/ext/ext/config/odoo-server.conf"
# pidfile
PIDFILE=/var/run/$NAME.pid
LOGFILE=/var/log/odoo/<%= @instance %>/odoo-server.log
# Additional options that are passed to the Daemon.
DAEMON_OPTS="-c $CONFIGFILE"
DAEMON_OPTS="-c $CONFIGFILE --db-filter $FILTER --xmlrpc-port <%= @odooport %> --longpolling-port <%= @odooport_longpolling %> --logfile $LOGFILE"
[ -x $DAEMON ] || exit 0
[ -f $CONFIGFILE ] || exit 0
@ -40,13 +41,17 @@ checkpid() {
return 1
}
# Required, otherwise there are problems with sudoers-File,
# see file "Odoo_sudo_Startup_Error_20510316.odt" on Share
export LOGNAME=<%= @instance %>
case "${1}" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS}
--exec ${DAEMON} -d $WORKING_DIR -- ${DAEMON_OPTS}
echo "${NAME}."
;;
@ -70,7 +75,7 @@ case "${1}" in
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS}
--exec ${DAEMON} -d $WORKING_DIR -- ${DAEMON_OPTS}
echo "${NAME}."
;;
@ -83,3 +88,4 @@ case "${1}" in
esac
exit 0

View File

@ -1,42 +1,53 @@
<% if ssl == true %>
server {
listen 80 default_server;
server_name "xxxxx";
# Strict Transport Security
# add_header Strict-Transport-Security max-age=2592000;
rewrite ^ https://$server_name$request_uri? permanent;
listen 80;
server_name <%= @servername %>;
return 301 https://$host$request_uri;
}
<% end %>
upstream odoo-server {
server 127.0.0.1:8069 fail_timeout=3000s;
# Should be higher for DMI!
upstream odoo-server-<%= @instance %> {
server 127.0.0.1:<%= @odooport %> fail_timeout=3000s;
}
server {
listen 443 ssl default_server;
server_name _;
<% if ssl == true %>
listen 443 ssl;
<% else %>
listen 80;
<% end %>
server_name <%= @servername %>;
# Specifies the maximum accepted body size of a client request,
# as indicated by the request header Content-Length.
client_max_body_size 200m;
# log files
access_log /var/log/nginx/odoo-access.log;
error_log /var/log/nginx/odoo-error.log;
access_log /var/log/nginx/odoo-access-<%= @instance %>.log;
error_log /var/log/nginx/odoo-error-<%= @instance %>.log;
# increase proxy buffer to handle some OpenERP web requests
proxy_buffers 16 64k;
proxy_buffer_size 128k;
<% if ssl == true %>
# SSL config
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_ciphers HIGH:!aNULL:!MD5;
<% if servername =~ /.*camadeus.at$/ %>
ssl_certificate /etc/nginx/ssl/camadeus.at.crt;
ssl_certificate_key /etc/nginx/ssl/camadeus.at.key;
<% else %>
ssl_certificate /etc/nginx/ssl/<%= @instance %>.crt;
ssl_certificate_key /etc/nginx/ssl/<%= @instance %>.key;
<% end %>
<% end %>
location / {
proxy_pass http://odoo-server;
proxy_pass http://odoo-server-<%= @instance %>;
# force timeouts if the backend dies
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_read_timeout 300s;
@ -60,7 +71,8 @@ server {
proxy_cache_valid 200 60m;
proxy_buffering on;
expires 864000;
proxy_pass http://odoo-server;
proxy_pass http://odoo-server-<%= @instance %>;
}
}

View File

@ -0,0 +1,5 @@
#!/bin/sh
# info: restart Odoo server
# author: Camadeus GmbH
sudo /etc/init.d/odoo-server-<%= @instance %> restart

View File

@ -0,0 +1 @@
class { 'odoo': }

42
setup/puppet/setup_server.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/bash
HOST='tbd'
if [ $# -lt 1 ] || [ $# -gt 1 ]; then
echo "Usage: ./setup_server.sh <init|update>"
exit 1
fi
echo "Are you sure? [Press Y to confirm!]"
read ANSWER
if [ "$ANSWER" != "Y" ]; then
echo "Ok, good bye!"
exit 1
fi
TYPE=$1
USER=root
if [ "$TYPE" = "init" ]; then
ssh ${USER}@$HOST "apt-get update; apt-get install puppet; sudo echo '$HOST' > /etc/hostname; sudo /etc/init.d/hostname.sh start;"
ssh ${USER}@${HOST} "sudo apt-get install rsync"
ssh ${USER}@${HOST} "sudo puppet module install puppetlabs-postgresql"
ssh ${USER}@${HOST} "sudo puppet module install saz-sudo"
ssh ${USER}@${HOST} "sudo puppet module install thias-postfix"
fi
if [ "$TYPE" = "update" ]; then
USER=odoo
fi
# Copy to server
rsync -av --copy-links "site.pp" "${USER}@${HOST}:/tmp/site.pp"
rsync -arv --copy-links "modules" "${USER}@${HOST}:/tmp"
ssh ${USER}@${HOST} "sudo mv -f /tmp/site.pp /etc/puppet/manifests/site.pp"
ssh ${USER}@${HOST} "sudo rm -rf /etc/puppet/modules/odoo; sudo mv /tmp/modules/odoo /etc/puppet/modules; sudo rm -rf /tmp/modules"
ssh ${USER}@${HOST} "sudo puppet apply /etc/puppet/manifests/site.pp"

13
setup/puppet/site.pp Normal file
View File

@ -0,0 +1,13 @@
node default {
TODO
odoo::instance {'TODO':
db_pw => 'x54ef6t77t6ZZul3',
ssl => true,
servername => 'TODO.camadeus.at',
odooport => 8069,
odooport_longpolling => 8070,
}
}

1
setup/res.users.csv Normal file
View File

@ -0,0 +1 @@
id,name,login,email,groups_id/id,department_ids/id,tz,mobile,phone,function
1 id name login email groups_id/id department_ids/id tz mobile phone function

9
setup/restart_prod.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
# info: restart Odoo server
# author: Camadeus GmbH
USER=x
HOST=x
INSTANCE=x
ssh ${USER}@${HOST} "sudo service odoo-server-${INSTANCE} restart"