Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ff6cc7f2

Von Hans Peter Schlaepfer vor fast 4 Jahren hinzugefügt

  • ID ff6cc7f2acf47ac2d92fee29297a52cdc6c8f594
  • Vorgänger a2b05131
  • Nachfolger a4ff507d

Design 4.0: Aenderungen in templates/webpages/csv_import/..

Unterschiede anzeigen:

templates/webpages/csv_import/_form_banktransactions.html
1 1
[% USE LxERP %]
2 2
[% USE L %]
3 3
<tr>
4
 <th align="right">[%- LxERP.t8("Existing bank transactions") %]:</th>
5
 <td colspan="10">
4
 <th>[% LxERP.t8("Existing bank transactions") %]:</th>
5
 <td>
6 6
  [% opts = [ [ 'skip', LxERP.t8('Skip entry') ] , [ 'insert_new', LxERP.t8('Insert new') ] ] %]
7
  [% L.select_tag('settings.update_policy', opts, default = SELF.profile.get('update_policy'), style = 'width: 300px') %]
8
 </td>
7
  [% L.select_tag('settings.update_policy', opts, default = SELF.profile.get('update_policy'), class='wi-normal') %]
8
</td>
9 9
</tr>
templates/webpages/csv_import/_form_customers_vendors.html
2 2
[% USE L %]
3 3

  
4 4
<tr>
5
 <th align="right">[%- LxERP.t8('Target table') %]:</th>
6
 <td colspan="10">
5
 <th>[%- LxERP.t8('Target table') %]:</th>
6
 <td>
7 7
  [% opts = [ [ 'customer', LxERP.t8('Customers') ], [ 'vendor', LxERP.t8('Vendors') ] ] %]
8 8
  [% L.select_tag('settings.table', opts, default = SELF.profile.get('table'), style = 'width: 300px') %]
9 9
 </td>
10 10
</tr>
11 11

  
12 12
<tr>
13
 <th align="right">[%- LxERP.t8('Existing customers/vendors with same customer/vendor number') %]:</th>
14
 <td colspan="10">
13
 <th>[%- LxERP.t8('Existing customers/vendors with same customer/vendor number') %]:</th>
14
 <td>
15 15
  [% opts = [ [ 'update_existing', LxERP.t8('Update properties of existing entries') ], [ 'insert_new', LxERP.t8('Insert with new customer/vendor number') ], [ 'skip', LxERP.t8('Skip entry') ] ] %]
16 16
  [% L.select_tag('settings.update_policy', opts, default = SELF.profile.get('update_policy'), style = 'width: 300px') %]
17 17
 </td>
18 18
</tr>
19 19

  
20 20
<tr>
21
 <th align="right" valign="top">[%- LxERP.t8('Default taxzone') %]:</th>
22
 <td colspan="10" valign="top">
21
 <th>[%- LxERP.t8('Default taxzone') %]:</th>
22
 <td>
23 23
  [% L.select_tag('settings.default_taxzone', SELF.all_taxzones, default = SELF.profile.get('default_taxzone'), title_key = 'description', style => 'width: 300px') %]
24 24
 </td>
25 25
</tr>
templates/webpages/csv_import/_mapping_item.html
2 2
[% USE LxERP %]
3 3
[% USE L %]
4 4
[% USE T8 %]
5
 <tr class=listrow>
6
    <td><a class='remove_line interact cursor-pointer'>✘</a></td>
7
[%- IF item.from %]
8
  <td>[% L.hidden_tag('mappings[+].from', item.from) %][% item.from | html %]</td>
9
[%- ELSE %]
10
  <td>[% L.input_tag('mappings[+].from', '') %]</td>
11
[%- END %]
5

  
6
<tr>
7
  <td><a class='remove_line interact cursor-pointer'>✘</a></td>
8
  [% IF item.from %]
9
    <td>[% L.hidden_tag('mappings[+].from', item.from) %][% item.from | html %]</td>
10
  [% ELSE %]
11
    <td>[% L.input_tag('mappings[+].from', '') %]</td>
12
  [% END %]
12 13
  <td>[% L.select_tag('mappings[].to', SELF.displayable_columns, value_key='name', title_key='name', default=item.to) %]</td>
13
 </tr>
14
</tr>
14 15

  
templates/webpages/csv_import/form.html
2 2
[% USE LxERP %]
3 3
[% USE L %]
4 4
[% USE T8 %]
5
 <h1>[% FORM.title %]</h1>
6 5

  
7
 [%- INCLUDE 'common/flash.html' %]
6
<h1>[% FORM.title %]</h1>
8 7

  
9
 <form method="post" action="controller.pl" enctype="multipart/form-data" id="form">
10
  [% L.hidden_tag('form_sent', '1') %]
11
  [% L.hidden_tag('action', 'CsvImport/dispatch') %]
12
  [% L.hidden_tag('profile.type', SELF.profile.type) %]
13
  [% L.hidden_tag('tmp_profile_id', SELF.profile.id) %]
8
[% INCLUDE 'common/flash.html' %]
14 9

  
15
 [%- IF SELF.profile.get('dont_edit_profile') %]
10
<form method="post" action="controller.pl" enctype="multipart/form-data" id="form">
11
[% L.hidden_tag('form_sent', '1') %]
12
[% L.hidden_tag('action', 'CsvImport/dispatch') %]
13
[% L.hidden_tag('profile.type', SELF.profile.type) %]
14
[% L.hidden_tag('tmp_profile_id', SELF.profile.id) %]
15

  
16
[% IF SELF.profile.get('dont_edit_profile') %]
16 17
  [% L.hidden_tag('force_profile', 1) %]
17 18
  [% L.hidden_tag('profile.id', SELF.profile.id) %]
18
 [%- ELSE %][%# IF SELF.profile.get('dont_edit_profile') %]
19
  <h2>[%- LxERP.t8('Import profiles') %]</h2>
20 19

  
21
  <table>
22
   [%- IF SELF.profile.id %]
20
[% ELSE %]
21

  
22
<div class="wrapper">
23

  
24
<table class="tbl-horizontal">
25
  <caption>[% LxERP.t8('Import profiles') %]</caption>
26
  <colgroup><col class="wi-mediumsmall"><col class="wi-wide"></colgroup>
27
  <tbody>
28
    [% IF SELF.profile.id %]
23 29
    <tr>
24
     <th align="right">[%- LxERP.t8('Current profile') %]:</th>
25
     <td>[%- HTML.escape(SELF.profile.name) %]</td>
30
      <th>[% LxERP.t8('Current profile') %]:</th>
31
      <td><h3>[% HTML.escape(SELF.profile.name) %]</h3></td>
26 32
    </tr>
27
   [%- END %][%# IF SELF.profile.id %]
28

  
29
   [%- IF SELF.all_profiles.size %]
33
    [% END %]
34
    [% IF SELF.all_profiles.size %]
35
    <tr>
36
      <th>[% LxERP.t8('Existing profiles') %]:</th>
37
      <td>
38
        [% L.select_tag('profile.id', SELF.all_profiles, title_key = 'name', default = SELF.profile.id, style = 'width: 300px') %] <br>
39
        [% L.submit_tag('action_new', LxERP.t8('Load profile')) %]
40
        [% L.submit_tag('action_destroy', LxERP.t8('Delete profile'), confirm => LxERP.t8('Do you really want to delete this object?')) %]
41
      </td>
42
    </tr>
43
    [% END %]
30 44
    <tr>
31
     <th align="right">[%- LxERP.t8('Existing profiles') %]:</th>
32
     <td>
33
      [% L.select_tag('profile.id', SELF.all_profiles, title_key = 'name', default = SELF.profile.id, style = 'width: 300px') %]
34
     </td>
35
     <td>
36
      [% L.submit_tag('action_new', LxERP.t8('Load profile')) %]
37
      [% L.submit_tag('action_destroy', LxERP.t8('Delete profile'), confirm => LxERP.t8('Do you really want to delete this object?')) %]
38
     </td>
45
      <th>[% LxERP.t8('Save settings as') %]:</th>
46
      <td>
47
        [% L.input_tag('profile.name', '', style => 'width: 300px') %]<br>
48
        [% L.checkbox_tag('profile.is_default', label => LxERP.t8('Make default profile')) %]<br>
49
        <div class="buttons below">[% L.submit_tag('action_save', LxERP.t8('Save profile'), class='below') %]</div>
50
      </td>
39 51
    </tr>
40
   [%- END %][%# IF SELF.all_profiles.size %]
52
  </tbody>
53
</table>
41 54

  
42
   <tr>
43
    <th align="right" valign="top">[%- LxERP.t8('Save settings as') %]:</th>
44
    <td valign="top">
45
     [% L.input_tag('profile.name', '', style => 'width: 300px') %]
46
     <br>
47
     [% L.checkbox_tag('profile.is_default', label => LxERP.t8('Make default profile')) %]
48
    </td>
49
    <td valign="top">[% L.submit_tag('action_save', LxERP.t8('Save profile')) %]</td>
50
   </tr>
51
  </table>
55
</div><!-- /.wrapper -->
52 56

  
53
  <hr>
57
<div class="wrapper">
54 58

  
55
  <h2>[%- LxERP.t8('Help on column names') %]</h2>
59
<div class="col wi-verywide">
56 60

  
57
  <div class="help_toggle">
58
   <a href="#" onClick="javascript:$('.help_toggle').toggle()">[% LxERP.t8("Show help text") %]</a>
59
  </div>
61
<h3 class="caption">[% LxERP.t8('Settings') %][% IF SELF.profile.id %] [% 'for Profile' | $T8 %]«[% HTML.escape(SELF.profile.name) %][% END %]</h3>
60 62

  
61
  <div class="help_toggle" style="display:none">
62
   <p><a href="#" onClick="javascript:$('.help_toggle').toggle()">[% LxERP.t8("Hide help text") %]</a></p>
63

  
64
   [%- IF SELF.worker.is_multiplexed %]
65
     <table>
66
       <tr class="listheading">
67
         [%- FOREACH p = SELF.worker.profile %]
68
           <th>[%- p.row_ident %]</th>
69
         [%- END %][%# FOREACH SELF.worker.profile %]
70
       </tr>
71
       <tr style="vertical-align:top">
72
         [%- FOREACH p = SELF.worker.profile %]
73
           [% SET ri = p.row_ident %]
74
         <td>
75
           <table>
76
             <tr class="listheading">
77
               <th>[%- LxERP.t8('Column name') %]</th>
78
               <th>[%- LxERP.t8('Meaning') %]</th>
79
             </tr>
80

  
81
             [%- FOREACH row = SELF.displayable_columns.$ri %]
82
             <tr class="listrow[% loop.count % 2 %]">
83
               <td>[%- HTML.escape(row.name) %]</td>
84
               <td>[%- HTML.escape(row.description) %]</td>
85
             </tr>
86
             [%- END %][%# FOREACH SELF.displayable_columns.$ri %]
87
           </table>
88
         </td>
89
         [%- END %][%# FOREACH SELF.worker.profile %]
90
       </tr>
91
     </table>
92
   [%- ELSE %][%# IF SELF.worker.is_multiplexed %]
93
     <table>
94
       <tr class="listheading">
95
         <th>[%- LxERP.t8('Column name') %]</th>
96
         <th>[%- LxERP.t8('Meaning') %]</th>
97
       </tr>
98

  
99
       [%- FOREACH row = SELF.displayable_columns %]
100
       <tr class="listrow[% loop.count % 2 %]">
101
         <td>[%- HTML.escape(row.name) %]</td>
102
         <td>[%- HTML.escape(row.description) %]</td>
103
       </tr>
104
       [%- END %][%# FOREACH SELF.displayable_columns %]
105
     </table>
106
   [%- END %][%# SELF.worker.is_multiplexed %]
107

  
108
[%- IF SELF.type == 'contacts' %]
109
   <p>
110
    [%- LxERP.t8("You can update existing contacts by providing the 'cp_id' column with their database IDs. Otherwise: ") %]
111
    [%- LxERP.t8('At least one of the columns #1, customer, customernumber, customer_gln, vendor, vendornumber, vendor_gln (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'cp_cv_id') %]
112
   </p>
113

  
114
[%- ELSIF SELF.type == 'addresses' %]
115
   <p>
116
    [%- LxERP.t8('At least one of the columns #1, customer, customernumber, customer_gln, vendor, vendornumber, vendor_gln (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'trans_id') %]
117
   </p>
118

  
119
[%- ELSIF SELF.type == 'parts' %]
120
   <p>
121
    [1]:
122
    [% LxERP.t8('The three columns "make_X", "model_X" and "lastcost_X" with the same number "X" are used to import vendor part numbers and vendor prices.') %]
123
    [% LxERP.t8('The column triplets can occur multiple times with different numbers "X" each time (e.g. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).') %]
124
    [% LxERP.t8('The items are imported accoring do their number "X" regardless of the column order inside the file.') %]
125
    [% LxERP.t8('The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.') %]
126
   </p>
63
[% BLOCK panel_1 %]
64
<table class="tbl-horizontal">
65
  <colgroup><col class="wi-mediumsmall"><col class="wi-wide"></colgroup>
66
  <tbody>
67
    <tr>
68
      <th>[% LxERP.t8('Number Format') %]:</th>
69
      <td>[% L.select_tag('settings.numberformat', ['1.000,00', '1000,00', '1,000.00', '1000.00', "1'000.00"], default = SELF.profile.get('numberformat'), class='wi-normal') %]</td>
70
    </tr>
71
    <tr>
72
     <th>[% LxERP.t8('Date Format') %]:</th>
73
     <td>[% L.select_tag('settings.dateformat', ['dd.mm.yyyy', 'yyyy-mm-dd', 'dd/mm/yyyy', 'mm/dd/yyyy' ], default = SELF.profile.get('dateformat'), class='wi-normal') %]</td>
74
    </tr>
75
    <tr>
76
      <th>[% LxERP.t8('Charset') %]:</th>
77
      <td>[% L.select_tag('settings.charset', SELF.all_charsets, default = SELF.profile.get('charset'), class='wi-normal') %]</td>
78
    </tr>
79
    <tr>
80
      <th>[% LxERP.t8('Separator') %]:</th>
81
      <td>
82
      [% SET custom_sep_char = SELF.sep_char %]
83
      [% FOREACH entry = SELF.all_sep_chars %]
84
        [% IF SELF.sep_char == entry.first %] [% SET custom_sep_char = '' %] [% END %]
85
        [% L.radio_button_tag('sep_char', value => entry.first, label => entry.last, checked => SELF.sep_char == entry.first) %]<br>
86
      [% END %]
87
      [% L.radio_button_tag('sep_char', value => 'custom', checked => custom_sep_char != '') %]
88
      [% L.input_tag('custom_sep_char', custom_sep_char, size => 3, maxlength => 1) %]
89
      </td>
90
    </tr>
91
    <tr>
92
      <th>[% LxERP.t8('Quote character') %]:</th>
93
      <td>
94
        [% SET custom_quote_char = SELF.quote_char %]
95
        [% FOREACH entry = SELF.all_quote_chars %]
96
          [% IF SELF.quote_char == entry.first %] [% SET custom_quote_char = '' %] [% END %]
97
          [% L.radio_button_tag('quote_char', value => entry.first, label => entry.last, checked => SELF.quote_char == entry.first) %]<br>
98
        [% END %]
99
        [% L.radio_button_tag('quote_char', value => 'custom', checked => custom_quote_char != '') %]
100
        [% L.input_tag('custom_quote_char', custom_quote_char, size => 3, maxlength => 1) %]
101
      </td>
102
    </tr>
103
    <tr>
104
      <th>[% LxERP.t8('Escape character') %]:</th>
105
      <td>
106
        [% SET custom_escape_char = SELF.escape_char %]
107
        [% FOREACH entry = SELF.all_escape_chars %]
108
          [% IF SELF.escape_char == entry.first %] [% SET custom_escape_char = '' %] [% END %]
109
          [% L.radio_button_tag('escape_char', value => entry.first, label => entry.last, checked => SELF.escape_char == entry.first) %]<br>
110
        [% END %]
111
        [% L.radio_button_tag('escape_char', value => 'custom', checked => custom_escape_char != '') %]
112
        [% L.input_tag('custom_escape_char', custom_escape_char, size => 3, maxlength => 1) %]
113
      </td>
114
    </tr>
115
    [% duplicate_fields = SELF.worker.get_duplicate_check_fields() %]
116
    [% IF ( duplicate_fields.size ) %]
117
      <tr>
118
        <th>[% LxERP.t8('Check for duplicates') %]:</th>
119
        <td>
120
        [% FOREACH key = duplicate_fields.keys %]
121
          [% IF (SELF.profile.get('duplicates_'_ key) || (duplicate_fields.$key.default && !FORM.form_sent)) %] [% SET chckd=' checked' %]
122
          [% ELSE %] [% SET chckd='' %]
123
          [% END %]
124
          <input type="checkbox" name="settings.duplicates_[% key | html %]" id="settings.duplicates_[% key | html %]" value="1"[% chckd %]>
125
          <label for="settings.duplicates_[% key | html %]">[% duplicate_fields.$key.label | html %]</label><br>
126
        [% END %]
127
        </td>
128
      </tr>
129
      <tr>
130
        <th></th>
131
        <td>
132
          [% opts = [ [ 'no_check',  LxERP.t8('Do not check for duplicates') ],
133
                      [ 'check_csv', LxERP.t8('Discard duplicate entries in CSV file') ],
134
                      [ 'check_db',  LxERP.t8('Discard entries with duplicates in database or CSV file') ] ] %]
135
          [% L.select_tag('settings.duplicates', opts, default = SELF.profile.get('duplicates'), style = 'width: 300px') %]
136
        </td>
137
      </tr>
138
    [% END %]
139
    [% IF SELF.type == 'parts' %]
140
      [% INCLUDE 'csv_import/_form_parts.html' %]
141
    [% ELSIF SELF.type == 'customers_vendors' %]
142
      [% INCLUDE 'csv_import/_form_customers_vendors.html' %]
143
    [% ELSIF SELF.type == 'contacts' %]
144
      [% INCLUDE 'csv_import/_form_contacts.html' %]
145
    [% ELSIF SELF.type == 'inventories' %]
146
      [% INCLUDE 'csv_import/_form_inventories.html' %]
147
    [% ELSIF SELF.type == 'orders' %]
148
      [% INCLUDE 'csv_import/_form_orders.html' %]
149
    [% ELSIF SELF.type == 'delivery_orders' %]
150
      [% INCLUDE 'csv_import/_form_delivery_orders.html' %]
151
    [% ELSIF SELF.type == 'ar_transactions' %]
152
      [% INCLUDE 'csv_import/_form_artransactions.html' %]
153
    [% ELSIF SELF.type == 'bank_transactions' %]
154
      [% INCLUDE 'csv_import/_form_banktransactions.html' %]
155
    [% END %]
156
    <tr>
157
      <th>[% LxERP.t8('Preview Mode') %]:</th>
158
      <td>
159
        [% L.radio_button_tag('settings.full_preview', value=0, checked=!SELF.profile.get('full_preview'), label=LxERP.t8('Full Preview')) %]
160
        [% L.radio_button_tag('settings.full_preview', value=1, checked=SELF.profile.get('full_preview')==1, label=LxERP.t8('Only Lines with Notes or Errors')) %]
161
        [% L.radio_button_tag('settings.full_preview', value=2, checked=SELF.profile.get('full_preview')==2,   label=LxERP.t8('First 20 Lines')) %]
162
      </td>
163
    </tr>
164
    <tr>
165
      <th>[% LxERP.t8('Import file') %]:</th>
166
      <td>[% L.input_tag('file', '', type => 'file', accept => '*') %]</td>
167
    </tr>
168
    [% IF SELF.file.exists %]
169
      <tr>
170
        <th>[% LxERP.t8('Existing file on server') %]:</th>
171
        <td>[% LxERP.t8('Uploaded on #1, size #2 kB', SELF.file.displayable_mtime, LxERP.format_amount(SELF.file.size / 1024, 2)) %]</td>
172
      </tr>
173
    [% END %]
174
  </tbody>
175
</table>
176
[% END # panel_1 %]
177

  
178
[%
179
  INCLUDE 'common/toggle_panel.html'
180
  block_name    = 'panel_1'
181
  toggle_class  = 'toggle_panel_1'
182
  button_closed = LxERP.t8("Show settings")
183
  button_open   = LxERP.t8("Hide settings")
184
%]
185

  
186
</div><!-- /.col -->
187
<div class="col wi-verywide">
188

  
189
[% UNLESS SELF.worker.is_multiplexed %]
190

  
191
<h3>[% 'Mappings (csv_import)' | $T8 %]</h3>
192

  
193
[% BLOCK panel_2 %]
194
<p>[% 'These mappings can be used to map heading from non standard csv files to known columns. These will also be saved in profiles, so you can save profiles for every source of formats.' | $T8 %]</p>
195
<table id="csv_import_mappings" class="tbl-list">
196
  <thead>
197
    <tr>
198
      <th>[% 'Action' | $T8 %]</th>
199
      <th>[% 'Text in CSV File' | $T8 %]</th>
200
      <th>[% 'Known Column' | $T8 %]</th>
201
    </tr>
202
  </thead>
203
  <tbody>
204
    <tr id="mapping_empty" style="display:none">
205
      <td colspan="3">[% 'There is nothing here yet (csv_import)' | $T8 %]</td>
206
    </tr>
207
    [% FOREACH row = SELF.mappings %]
208
      [% PROCESS 'csv_import/_mapping_item.html', item=row IF row.from %]
209
    [% END %]
210
    [% PROCESS 'csv_import/_mapping_item.html', item={} %]
211
  </tbody>
212
</table>
213
<div class="button">
214
  <input type="button" id="add_empty_mapping_line" value="[% 'Add empty line (csv_import)' | $T8 %]">
215
  <input type="button" id="add_mapping_from_upload" value="[% 'Add headers from last uploaded file (csv_import)' | $T8 %]">
216
</div>
217
[% END # panel_2 %]
218

  
219
[%
220
  #INCLUDE 'common/toggle_panel.html'
221
  block_name    = 'panel_2'
222
  toggle_class  = 'toggle_panel_2'
223
  button_closed = LxERP.t8("Show mappings (csv_import)")
224
  button_open   = LxERP.t8("Hide mappings (csv_import)s")
225
%]
226

  
227
[% END # UNLESS SELF.worker.is_multiplexed %]
228

  
229
[% IF SELF.deferred %]
230
  <div id="results">
231
    [% PROCESS 'csv_import/_deferred_results.html' %]
232
  </div>
233
[% END %]
234

  
235

  
236
<h3 class="caption">[% LxERP.t8('Help on column names') %]</h3>
237

  
238
[% BLOCK panel_3 %]
239
  [% IF SELF.worker.is_multiplexed %]
240
    <table>
241
      <tbody>
242
        <tr>
243
          [% FOREACH p = SELF.worker.profile %]
244
            <th>[% p.row_ident %]</th>
245
          [% END %]
246
        </tr>
247
        <tr>
248
          [% FOREACH p = SELF.worker.profile %]
249
            [% SET ri = p.row_ident %]
250
            <td>
251
              <table class="tbl-list">
252
                <thead>
253
                  <tr>
254
                    <th>[% LxERP.t8('Column name') %]</th>
255
                    <th>[% LxERP.t8('Meaning') %]</th>
256
                  </tr>
257
                </thead>
258
                <tbody>
259
                  [% FOREACH row = SELF.displayable_columns.$ri %]
260
                    <tr>
261
                      <td>[% HTML.escape(row.name) %]</td>
262
                      <td>[% HTML.escape(row.description) %]</td>
263
                    </tr>
264
                  [% END %]
265
                </tbody>
266
              </table>
267
            </td>
268
          [% END %]
269
        </tr>
270
      </tbody>
271
    </table>
272
  [% ELSE %]
273
    <table class="tbl-list">
274
      <thead>
275
        <tr>
276
          <th>[% LxERP.t8('Column name') %]</th>
277
          <th>[% LxERP.t8('Meaning') %]</th>
278
        </tr>
279
      </thead>
280
      <tbody>
281
        [% FOREACH row = SELF.displayable_columns %]
282
        <tr>
283
          <td>[% HTML.escape(row.name) %]</td>
284
          <td>[% HTML.escape(row.description) %]</td>
285
        </tr>
286
        [% END %]
287
      </tbody>
288
    </table>
289
  [% END %]
290
  [% IF SELF.type == 'contacts' %]
127 291
    <p>
128
    [2]:
129
    [% LxERP.t8('Onhand only sets the quantity in master data, not in inventory. This is only a legacy info field and will be overwritten as soon as a inventory transfer happens.') %]
130
   </p>
131
   <p>
132
    [3]:
133
    [% LxERP.t8("If the article type is set to 'mixed' then a column called 'part_type' or called 'pclass' must be present.") %]
134
    [% LxERP.t8("Type can be either 'part', 'service' or 'assembly'.") %]
135
    [%- LxERP.t8("If column 'pclass' is present the article type is then irrelevant or used as default ") %]
136
    [% LxERP.t8("The 'pclass' column has the same abbreviation like a part export. The first letter is for the type Part,Assembly or Service, the second(and third) for Part Classification") %]
137
   </p>
138

  
139
[%- ELSIF SELF.type == 'inventories' %]
140
   <p>
141
    [%- LxERP.t8('One of the columns "qty" or "target_qty" must be given. If "target_qty" is given, the quantity to transfer for each transfer will be calculate, so that the quantity for this part, warehouse and bin will result in the given "target_qty" after each transfer.') %]
142
   </p>
143

  
144
[%- ELSIF SELF.type == 'orders' OR SELF.type == 'delivery_orders' OR SELF.type == 'ar_transactions' %]
145
   <p>
146
    [1]:
147
    [% LxERP.t8('The column "datatype" must be present and must be at the same position / column in each data set. The values must be the row names (see settings) for order and item data respectively.') %]
148
   </p>
149
   [%- IF SELF.type == 'orders' OR SELF.type == 'ar_transactions' %]
292
      [% LxERP.t8("You can update existing contacts by providing the 'cp_id' column with their database IDs. Otherwise: ") %]
293
      [% LxERP.t8('At least one of the columns #1, customer, customernumber, customer_gln, vendor, vendornumber, vendor_gln (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'cp_cv_id') %]
294
    </p>
295
  [% ELSIF SELF.type == 'addresses' %]
296
    <p>[% LxERP.t8('At least one of the columns #1, customer, customernumber, customer_gln, vendor, vendornumber, vendor_gln (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'trans_id') %]</p>
297
  [% ELSIF SELF.type == 'parts' %]
150 298
    <p>
151
     [2]:
152
     [%- LxERP.t8('Amount and net amount are calculated by kivitendo. "verify_amount" and "verify_netamount" can be used for sanity checks.') %]<br>
153
     [%- LxERP.t8('If amounts differ more than "Maximal amount difference" (see settings), this item is marked as invalid.') %]<br>
299
      [1]:
300
      [% LxERP.t8('The three columns "make_X", "model_X" and "lastcost_X" with the same number "X" are used to import vendor part numbers and vendor prices.') %]
301
      [% LxERP.t8('The column triplets can occur multiple times with different numbers "X" each time (e.g. "make_1", "model_1", "lastcost_1", "make_2", "model_2", "lastcost_2", "make_3", "model_3", "lastcost_3" etc).') %]
302
      [% LxERP.t8('The items are imported accoring do their number "X" regardless of the column order inside the file.') %]
303
      [% LxERP.t8('The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.') %]
154 304
    </p>
155
   [%- END %]
156
[%- END %][%# IF SELF.type == … %]
305
    <p>
306
      [2]:
307
      [% LxERP.t8('Onhand only sets the quantity in master data, not in inventory. This is only a legacy info field and will be overwritten as soon as a inventory transfer happens.') %]
308
    </p>
309
    <p>
310
      [3]:
311
      [% LxERP.t8("If the article type is set to 'mixed' then a column called 'part_type' or called 'pclass' must be present.") %]
312
      [% LxERP.t8("Type can be either 'part', 'service' or 'assembly'.") %]
313
      [% LxERP.t8("If column 'pclass' is present the article type is then irrelevant or used as default ") %]
314
      [% LxERP.t8("The 'pclass' column has the same abbreviation like a part export. The first letter is for the type Part,Assembly or Service, the second(and third) for Part Classification") %]
315
    </p>
316
  [% ELSIF SELF.type == 'inventories' %]
317
    <p>[% LxERP.t8('One of the columns "qty" or "target_qty" must be given. If "target_qty" is given, the quantity to transfer for each transfer will be calculate, so that the quantity for this part, warehouse and bin will result in the given "target_qty" after each transfer.') %]</p>
318
  [% ELSIF SELF.type == 'orders' OR SELF.type == 'delivery_orders' OR SELF.type == 'ar_transactions' %]
319
    <p>
320
      [1]:
321
      [% LxERP.t8('The column "datatype" must be present and must be at the same position / column in each data set. The values must be the row names (see settings) for order and item data respectively.') %]
322
    </p>
323
    <p>
324
    [% IF SELF.type == 'orders' OR SELF.type == 'ar_transactions' %]
325
      <p>
326
        [2]:
327
        [% LxERP.t8('Amount and net amount are calculated by kivitendo. "verify_amount" and "verify_netamount" can be used for sanity checks.') %]<br>
328
        [% LxERP.t8('If amounts differ more than "Maximal amount difference" (see settings), this item is marked as invalid.') %]<br>
329
      </p>
330
    [% END %]
331
  [% END %][%# IF SELF.type == … %]
332
  <p>[% L.submit_tag('action_download_sample', LxERP.t8('Download sample file')) %]</p>
333
[% END # panel_3 %]
157 334

  
158
   <p>
159
    [%- L.submit_tag('action_download_sample', LxERP.t8('Download sample file')) %]
160
   </p>
335
[%
336
  #INCLUDE 'common/toggle_panel.html'
337
  block_name    = 'panel_3'
338
  toggle_class  = 'toggle_panel_3'
339
  button_closed = LxERP.t8("Show help text")
340
  button_open   = LxERP.t8("Hide help text")
341
%]
161 342

  
162
  </div>
163 343

  
164
  <hr>
344
</div><!-- /.col -->
165 345

  
166
  <h2>[%- LxERP.t8('Settings') %]</h2>
346
[% END %]<!-- # /ELSE SELF.profile.get('dont_edit_profile') -->
167 347

  
168
  <div class="settings_toggle"[% UNLESS SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
169
   <a href="#" onClick="javascript:$('.settings_toggle').toggle()">[% LxERP.t8("Show settings") %]</a>
170
  </div>
171 348

  
172
  <div class="settings_toggle"[% IF SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
173
   <p><a href="#" onClick="javascript:$('.settings_toggle').toggle()">[% LxERP.t8("Hide settings") %]</a></p>
174

  
175
  <table>
176
   <tr>
177
    <th align="right">[%- LxERP.t8('Number Format') %]:</th>
178
    <td colspan="10">
179
     [% L.select_tag('settings.numberformat', ['1.000,00', '1000,00', '1,000.00', '1000.00', "1'000.00"], default = SELF.profile.get('numberformat'), style = 'width: 300px') %]
180
    </td>
181
   </tr>
182

  
183
   <tr>
184
    <th align="right">[%- LxERP.t8('Date Format') %]:</th>
185
    <td colspan="10">
186
     [% L.select_tag('settings.dateformat', ['dd.mm.yyyy', 'yyyy-mm-dd', 'dd/mm/yyyy', 'mm/dd/yyyy' ], default = SELF.profile.get('dateformat'), style = 'width: 300px') %]
187
    </td>
188
   </tr>
189

  
190
   <tr>
191
    <th align="right">[%- LxERP.t8('Charset') %]:</th>
192
    <td colspan="10">[% L.select_tag('settings.charset', SELF.all_charsets, default = SELF.profile.get('charset'), style = 'width: 300px') %]</td>
193
   </tr>
194

  
195
   <tr>
196
    <th align="right">[%- LxERP.t8('Separator') %]:</th>
197
    [% SET custom_sep_char = SELF.sep_char %]
198
    [% FOREACH entry = SELF.all_sep_chars %]
199
     <td>
200
      [% IF SELF.sep_char == entry.first %] [% SET custom_sep_char = '' %] [%- END %]
201
      [% L.radio_button_tag('sep_char', value => entry.first, label => entry.last, checked => SELF.sep_char == entry.first) %]
202
     </td>
203
    [%- END %][%# FOREACH SELF.all_sep_chars %]
204

  
205
    <td>
206
     [% L.radio_button_tag('sep_char', value => 'custom', checked => custom_sep_char != '') %]
207
     [% L.input_tag('custom_sep_char', custom_sep_char, size => 3, maxlength => 1) %]
208
    </td>
209
   </tr>
210

  
211
   <tr>
212
    <th align="right">[%- LxERP.t8('Quote character') %]:</th>
213
    [% SET custom_quote_char = SELF.quote_char %]
214
    [% FOREACH entry = SELF.all_quote_chars %]
215
     <td>
216
      [% IF SELF.quote_char == entry.first %] [% SET custom_quote_char = '' %] [%- END %]
217
      [% L.radio_button_tag('quote_char', value => entry.first, label => entry.last, checked => SELF.quote_char == entry.first) %]
218
     </td>
219
    [%- END %][%# FOREACH SELF.all_quote_chars %]
220

  
221
    <td>
222
     [% L.radio_button_tag('quote_char', value => 'custom', checked => custom_quote_char != '') %]
223
     [% L.input_tag('custom_quote_char', custom_quote_char, size => 3, maxlength => 1) %]
224
    </td>
225
   </tr>
226

  
227
   <tr>
228
    <th align="right">[%- LxERP.t8('Escape character') %]:</th>
229
    [% SET custom_escape_char = SELF.escape_char %]
230
    [% FOREACH entry = SELF.all_escape_chars %]
231
     <td>
232
      [% IF SELF.escape_char == entry.first %] [% SET custom_escape_char = '' %] [%- END %]
233
      [% L.radio_button_tag('escape_char', value => entry.first, label => entry.last, checked => SELF.escape_char == entry.first) %]
234
     </td>
235
    [%- END %][%# FOREACH SELF.all_escape_chars %]
236

  
237
    <td>
238
     [% L.radio_button_tag('escape_char', value => 'custom', checked => custom_escape_char != '') %]
239
     [% L.input_tag('custom_escape_char', custom_escape_char, size => 3, maxlength => 1) %]
240
    </td>
241
   </tr>
242

  
243
   [% duplicate_fields = SELF.worker.get_duplicate_check_fields() %]
244
   [% IF ( duplicate_fields.size ) %]
245
     <tr>
246
       <th align="right">[%- LxERP.t8('Check for duplicates') %]:</th>
247

  
248
       <td colspan=10>
249
         [% FOREACH key = duplicate_fields.keys %]
250
           <input type="checkbox" name="settings.duplicates_[% key | html %]" id="settings.duplicates_[% key | html %]" value="1"[% IF ( SELF.profile.get('duplicates_'_ key) || (duplicate_fields.$key.default && !FORM.form_sent ) ) %] checked="checked"[% END %]>
251
           <label for="settings.duplicates_[% key | html %]">[% duplicate_fields.$key.label | html %]</label>
252
         [% END %][%# FOREACH duplicate_fields.keys %]
253
       </td>
254
     </tr>
255

  
256
     <tr>
257
       <th align="right"></th>
258

  
259
       <td colspan=10>
260
         [% opts = [ [ 'no_check',  LxERP.t8('Do not check for duplicates') ],
261
                     [ 'check_csv', LxERP.t8('Discard duplicate entries in CSV file') ],
262
                     [ 'check_db',  LxERP.t8('Discard entries with duplicates in database or CSV file') ] ] %]
263
         [% L.select_tag('settings.duplicates', opts, default = SELF.profile.get('duplicates'), style = 'width: 300px') %]
264
       </td>
265
     </tr>
266
   [% END %][%# IF duplicate_fields.size %]
267

  
268
[%- IF SELF.type == 'parts' %]
269
 [%- INCLUDE 'csv_import/_form_parts.html' %]
270
[%- ELSIF SELF.type == 'customers_vendors' %]
271
 [%- INCLUDE 'csv_import/_form_customers_vendors.html' %]
272
[%- ELSIF SELF.type == 'contacts' %]
273
 [%- INCLUDE 'csv_import/_form_contacts.html' %]
274
[%- ELSIF SELF.type == 'inventories' %]
275
 [%- INCLUDE 'csv_import/_form_inventories.html' %]
276
[%- ELSIF SELF.type == 'orders' %]
277
 [%- INCLUDE 'csv_import/_form_orders.html' %]
278
[%- ELSIF SELF.type == 'delivery_orders' %]
279
 [%- INCLUDE 'csv_import/_form_delivery_orders.html' %]
280
[%- ELSIF SELF.type == 'ar_transactions' %]
281
 [%- INCLUDE 'csv_import/_form_artransactions.html' %]
282
[%- ELSIF SELF.type == 'bank_transactions' %]
283
 [%- INCLUDE 'csv_import/_form_banktransactions.html' %]
284
[%- END %]
285

  
286
   <tr>
287
    <th align="right">[%- LxERP.t8('Preview Mode') %]:</th>
288
    <td colspan="10">
289
      [% L.radio_button_tag('settings.full_preview', value=0, checked=!SELF.profile.get('full_preview'),   label=LxERP.t8('Full Preview')) %]
290
      [% L.radio_button_tag('settings.full_preview', value=1, checked=SELF.profile.get('full_preview')==1, label=LxERP.t8('Only Lines with Notes or Errors')) %]
291
      [% L.radio_button_tag('settings.full_preview', value=2, checked=SELF.profile.get('full_preview')==2, label=LxERP.t8('First 20 Lines')) %]
292
    </td>
293
   </tr>
294

  
295
   <tr>
296
    <th align="right">[%- LxERP.t8('Import file') %]:</th>
297
    <td colspan="10">[% L.input_tag('file', '', type => 'file', accept => '*') %]</td>
298
   </tr>
299

  
300
   [%- IF SELF.file.exists %]
301
    <tr>
302
     <th align="right">[%- LxERP.t8('Existing file on server') %]:</th>
303
     <td colspan="10">[%- LxERP.t8('Uploaded on #1, size #2 kB', SELF.file.displayable_mtime, LxERP.format_amount(SELF.file.size / 1024, 2)) %]</td>
304
    </tr>
305
   [%- END %][%# IF SELF.file.exists %]
306 349

  
307
  </table>
350
</form>
308 351

  
309
  </div>
310
  <hr>
352
<div class="col wi-wide">
311 353

  
312
[%- UNLESS SELF.worker.is_multiplexed %]
313
  <h2>[% 'Mappings (csv_import)' | $T8 %]</h2>
314 354

  
315
  <div class="mappings_toggle"[% UNLESS SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
316
   <a href="#" onClick="javascript:$('.mappings_toggle').toggle()">[% LxERP.t8("Show mappings (csv_import)") %]</a>
317
  </div>
318
  <div class="mappings_toggle"[% IF SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
319
   <p><a href="#" onClick="javascript:$('.mappings_toggle').toggle()">[% LxERP.t8("Hide mappings (csv_import)") %]</a></p>
320

  
321
    <p>[% 'These mappings can be used to map heading from non standard csv files to known columns. These will also be saved in profiles, so you can save profiles for every source of formats.' | $T8 %]</p>
322

  
323
  <table id="csv_import_mappings">
324
   <tr class=listheading>
325
    <th></th>
326
    <th>[% 'Text in CSV File' | $T8 %]</th>
327
    <th>[% 'Known Column' | $T8 %]</th>
328
   </tr>
329
   <tr id='mapping_empty' style='display:none'>
330
    <td colspan=3>[% 'There is nothing here yet (csv_import)' | $T8 %]</td>
331
   </tr>
332
[%- FOREACH row = SELF.mappings %]
333
   [% PROCESS 'csv_import/_mapping_item.html', item=row IF row.from %]
334
[%- END %][%# FOREACH SELF.mappings %]
335
   [% PROCESS 'csv_import/_mapping_item.html', item={} %]
336
  </table>
337

  
338
  <input type=button id='add_empty_mapping_line' value='[% 'Add empty line (csv_import)' | $T8 %]'>
339
  <input type=button id='add_mapping_from_upload' value='[% 'Add headers from last uploaded file (csv_import)' | $T8 %]'>
340 355

  
341
  </div>
342
  <hr>
343
[%- END %][%# UNLESS SELF.worker.is_multiplexed %]
344
[%- END %][%# IF SELF.profile.get('dont_edit_profile') %]
345
 </form>
346 356

  
347
 <div id='results'>
348
 [%- IF SELF.deferred %]
349
   [%- PROCESS 'csv_import/_deferred_results.html' %]
350
 [%- END %][%# IF SELF.deferred %]
351
 </div>
357
</div><!-- /.col -->
358

  
359
</div><!-- /.wrapper -->
352 360

  
353 361

  
354
 <script type="text/javascript">
362
<script type="text/javascript">
355 363
  <!--
356 364
    $(document).ready(function() {
357 365
      $('#action_save').click(function() {
......
369 377
      $('#csv_import_mappings').on('click', '.remove_line', function(){ $(this).closest('tr').remove(); if (1==$('#csv_import_mappings tr:visible').length) $('#mapping_empty').show() });
370 378
    });
371 379
    -->
372
 </script>
380
</script>
templates/webpages/csv_import/report.html
2 2
[% USE LxERP %]
3 3
[% USE L %]
4 4
 <h2>
5
 [%- IF SELF.report.test_mode %]
6
  [%- LxERP.t8('Import preview') %]
7
 [%- ELSE %]
8
  [%- LxERP.t8('Import result') %]
9
 [%- END %]
10
 [%- IF SELF.num_errors -%]
5
 [% IF SELF.report.test_mode %]
6
  [% LxERP.t8('Import preview') %]
7
 [% ELSE %]
8
  [% LxERP.t8('Import result') %]
9
 [% END %]
10
 [% IF SELF.num_errors %]
11 11
   <font color="red">([%- SELF.num_errors -%]&nbsp;[%- LxERP.t8('Errors') -%])</font>
12
 [%- END -%]
12
 [% END %]
13 13
</h2>
14 14

  
15
[%- IF SELF.report.test_mode %]
15
[% IF SELF.report.test_mode %]
16 16
 <p>
17 17
  [% LxERP.t8("The following is only a preview.") %]
18 18
  [% LxERP.t8("No entries have been imported yet.") %]
19 19
 </p>
20
[%- END %]
20
[% END %]
21 21

  
22
[%- PROCESS 'common/paginate.html' pages=SELF.pages, base_url = SELF.base_url %]
22
[% PROCESS 'common/paginate.html' pages=SELF.pages, base_url = SELF.base_url %]
23 23
 <table>
24 24

  
25
[%- SET max_col = 0 %]
26
[%- FOREACH rownum = SELF.display_rows %]
27
  [%- SET max_col = max_col > SELF.report_rows.${rownum}.size ? max_col : SELF.report_rows.${rownum}.size  %]
28
  [%- LAST IF rownum >= SELF.report_numheaders %]
29
[%- END %]
25
[% SET max_col = 0 %]
26
[% FOREACH rownum = SELF.display_rows %]
27
  [% SET max_col = max_col > SELF.report_rows.${rownum}.size ? max_col : SELF.report_rows.${rownum}.size  %]
28
  [% LAST IF rownum >= SELF.report_numheaders %]
29
[% END %]
30 30

  
31
[%- FOREACH rownum = SELF.display_rows %]
32
 [%- SET to_pad = max_col - SELF.report_rows.${rownum}.size %]
33
 [%- IF rownum < SELF.report_numheaders %]
34
  <tr class="listheading">
35
  [%- FOREACH value = SELF.report_rows.${rownum} %]
31
[% FOREACH rownum = SELF.display_rows %]
32
 [% SET to_pad = max_col - SELF.report_rows.${rownum}.size %]
33
 [% IF rownum < SELF.report_numheaders %]
34
  <tr>
35
  [% FOREACH value = SELF.report_rows.${rownum} %]
36 36
   <th>[% value | html %]</th>
37
  [%- END %]
38
   [%- IF to_pad -%]<th style="text-align:center" colspan="[%- to_pad -%]">-</th>[%- END -%]
39
   <th>[%- LxERP.t8('Notes') %]</th>
37
  [% END %]
38
   [% IF to_pad %]<th style="text-align:center" colspan="[% to_pad %]">-</th>[% END %]
39
   <th>[% LxERP.t8('Notes') %]</th>
40 40
  </tr>
41
 [%- ELSE %]
41
 [% ELSE %]
42 42
  [% csv_import_report_errors = SELF.report_status.${rownum}.errors %]
43 43
  <tr class="listrow[% IF csv_import_report_errors && csv_import_report_errors.size %]_error[% END %][% (loop.count + SELF.report_numheaders) % 2 %]">
44
  [%- FOREACH value = SELF.report_rows.${rownum} %]
45
   <td>[%- value | html  %]</td>
46
  [%- END %]
47
   [%- IF to_pad -%]<td align="center" colspan="[%- to_pad -%]">-</td>[%- END -%]
44
  [% FOREACH value = SELF.report_rows.${rownum} %]
45
   <td>[% value | html  %]</td>
46
  [% END %]
47
   [% IF to_pad %]<td colspan="[% to_pad %]">-</td>[% END %]
48 48
   <td>
49
    [%- FOREACH error = csv_import_report_errors %][%- error | html %][% UNLESS loop.last %]<br>[%- END %][%- END %]
50
    [%- FOREACH info  = SELF.report_status.${rownum}.information %][% IF rownum >= SELF.report_numheaders || csv_import_report_errors.size %]<br>[%- END %][%- info | html %][%- END %]
49
    [% FOREACH error = csv_import_report_errors %][% error | html %][% UNLESS loop.last %]<br>[% END %][% END %]
50
    [% FOREACH info  = SELF.report_status.${rownum}.information %][% IF rownum >= SELF.report_numheaders || csv_import_report_errors.size %]<br>[% END %][% info | html %][% END %]
51 51
   </td>
52 52
  </tr>
53
 [%- END %]
54
[%- END %]
53
 [% END %]
54
[% END %]
55 55

  
56 56
 </table>
57 57

  
58
[%- PROCESS 'common/paginate.html' pages=SELF.pages, base_url = SELF.base_url %]
58
[% PROCESS 'common/paginate.html' pages=SELF.pages, base_url = SELF.base_url %]
59 59

  
60 60
<script type='text/javascript'>
61 61
  $(function(){
62
    [%- IF SELF.reporterror %]
62
    [% IF SELF.reporterror %]
63 63
      kivi.clear_flash('info',0);
64 64
      kivi.display_flash('error','[% SELF.reporterror %]',0);
65
    [%- ELSIF SELF.report.test_mode %]
65
    [% ELSIF SELF.report.test_mode %]
66 66
      kivi.ActionBar.Action('#action_import').enable();
67
    [%- END %]
67
    [% END %]
68 68
  });
69 69
</script>

Auch abrufbar als: Unified diff