4a9672b8fd1193678856953806e55c761c5309ee
[kivitendo-erp.git] / templates / webpages / csv_import / form.html
1 [%- USE HTML %]
2 [%- USE LxERP %]
3 [%- USE L %]
4 [%- USE T8 %]
5
6  <div class="listtop">[% FORM.title %]</div>
7
8  [%- INCLUDE 'common/flash.html' %]
9
10  <form method="post" action="controller.pl" enctype="multipart/form-data">
11   [% L.hidden_tag('form_sent', '1') %]
12   [% L.hidden_tag('action', 'CsvImport/dispatch') %]
13   [% L.hidden_tag('profile.type', SELF.profile.type) %]
14
15   <h2>[%- LxERP.t8('Import profiles') %]</h2>
16
17   <table>
18    [%- IF SELF.profile.id %]
19     <tr>
20      <th align="right">[%- LxERP.t8('Current profile') %]:</th>
21      <td>[%- HTML.escape(SELF.profile.name) %]</td>
22     </tr>
23    [%- END %]
24
25    [%- IF SELF.all_profiles.size %]
26     <tr>
27      <th align="right">[%- LxERP.t8('Existing profiles') %]:</th>
28      <td>
29       [% L.select_tag('profile.id', SELF.all_profiles, title_key = 'name', default = SELF.profile.id, style = 'width: 300px') %]
30      </td>
31      <td>
32       [% L.submit_tag('action_new', LxERP.t8('Load profile')) %]
33       [% L.submit_tag('action_destroy', LxERP.t8('Delete profile'), confirm => LxERP.t8('Do you really want to delete this object?')) %]
34      </td>
35     </tr>
36    [%- END %]
37
38    <tr>
39     <th align="right" valign="top">[%- LxERP.t8('Save settings as') %]:</th>
40     <td valign="top">
41      [% L.input_tag('profile.name', '', style => 'width: 300px') %]
42      <br>
43      [% L.checkbox_tag('profile.is_default', label => LxERP.t8('Make default profile')) %]
44     </td>
45     <td valign="top">[% L.submit_tag('action_save', LxERP.t8('Save profile')) %]</td>
46    </tr>
47   </table>
48
49   <hr>
50
51   <h2>[%- LxERP.t8('Help on column names') %]</h2>
52
53   <div class="help_toggle">
54    <a href="#" onClick="javascript:$('.help_toggle').toggle()">[% LxERP.t8("Show help text") %]</a>
55   </div>
56
57   <div class="help_toggle" style="display:none">
58    <p><a href="#" onClick="javascript:$('.help_toggle').toggle()">[% LxERP.t8("Hide help text") %]</a></p>
59
60    [%- IF SELF.worker.is_multiplexed %]
61      <table>
62        <tr class="listheading">
63          [%- FOREACH p = SELF.worker.profile %]
64            <th>[%- p.row_ident %]</th>
65          [%- END %]
66        </tr>
67        <tr class="listrow[% loop.count % 2 %]">
68          [%- FOREACH p = SELF.worker.profile %]
69            [% SET ri = p.row_ident %]
70          <td>
71            <table>
72              <tr class="listheading">
73                <th>[%- LxERP.t8('Column name') %]</th>
74                <th>[%- LxERP.t8('Meaning') %]</th>
75              </tr>
76
77              [%- FOREACH row = SELF.displayable_columns.$ri %]
78              <tr class="listrow[% loop.count % 2 %]">
79                <td>[%- HTML.escape(row.name) %]</td>
80                <td>[%- HTML.escape(row.description) %]</td>
81              </tr>
82              [%- END %]
83            </table>
84          </td>
85          [%- END %]
86        </tr>
87      </table>
88    [%- ELSE %]
89      <table>
90        <tr class="listheading">
91          <th>[%- LxERP.t8('Column name') %]</th>
92          <th>[%- LxERP.t8('Meaning') %]</th>
93        </tr>
94
95        [%- FOREACH row = SELF.displayable_columns %]
96        <tr class="listrow[% loop.count % 2 %]">
97          <td>[%- HTML.escape(row.name) %]</td>
98          <td>[%- HTML.escape(row.description) %]</td>
99        </tr>
100        [%- END %]
101      </table>
102    [%- END %]
103
104 [%- IF SELF.type == 'contacts' %]
105    <p>
106     [%- LxERP.t8("You can update existing contacts by providing the 'cp_id' column with their database IDs. Otherwise: ") %]
107     [%- LxERP.t8('At least one of the columns #1, customer, customernumber, vendor, vendornumber (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'cp_cv_id') %]
108    </p>
109
110 [%- ELSIF SELF.type == 'addresses' %]
111    <p>
112     [%- LxERP.t8('At least one of the columns #1, customer, customernumber, vendor, vendornumber (depending on the target table) is required for matching the entry to an existing customer or vendor.', 'trans_id') %]
113    </p>
114
115 [%- ELSIF SELF.type == 'parts' %]
116    <p>
117     [%- LxERP.t8("If the article type is set to 'mixed' then a column called 'type' must be present.") %]
118     [% LxERP.t8("Type can be either 'part' or 'service'.") %]
119    </p>
120
121    <p>
122     [1]:
123     [% 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.') %]
124     [% 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).') %]
125     [% LxERP.t8('The items are imported accoring do their number "X" regardless of the column order inside the file.') %]
126     [% LxERP.t8('The column "make_X" can contain either a vendor\'s database ID, a vendor number or a vendor\'s name.') %]
127    </p>
128     <p>
129     [2]:
130     [% 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.') %]
131    </p>
132
133 [%- ELSIF SELF.type == 'orders' %]
134    <p>
135     [1]:
136     [% LxERP.t8('The column "datatype" must be present and must be the first column. The values must be the row names (see settings) for order and item data respectively.') %]
137    </p>
138    <p>
139     [2]:
140     [%- LxERP.t8('Amount and net amount are calculated by kivitendo. "verify_amount" and "verify_netamount" can be used for sanity checks.') %]<br>
141     [%- LxERP.t8('If amounts differ more than "Maximal amount difference" (see settings), this item is marked as invalid.') %]<br>
142    </p>
143 [%- END %]
144
145    <p>
146     [%- L.submit_tag('action_download_sample', LxERP.t8('Download sample file')) %]
147    </p>
148
149   </div>
150
151   <hr>
152
153   <h2>[%- LxERP.t8('Settings') %]</h2>
154
155   <div class="settings_toggle"[% UNLESS SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
156    <a href="#" onClick="javascript:$('.settings_toggle').toggle()">[% LxERP.t8("Show settings") %]</a>
157   </div>
158
159   <div class="settings_toggle"[% IF SELF.deferred || SELF.import_status %] style="display:none"[% END %]>
160    <p><a href="#" onClick="javascript:$('.settings_toggle').toggle()">[% LxERP.t8("Hide settings") %]</a></p>
161
162   <table>
163    <tr>
164     <th align="right">[%- LxERP.t8('Number Format') %]:</th>
165     <td colspan="10">
166      [% L.select_tag('settings.numberformat', ['1.000,00', '1000,00', '1,000.00', '1000.00'], default = SELF.profile.get('numberformat'), style = 'width: 300px') %]
167     </td>
168    </tr>
169
170    <tr>
171     <th align="right">[%- LxERP.t8('Charset') %]:</th>
172     <td colspan="10">[% L.select_tag('settings.charset', SELF.all_charsets, default = SELF.profile.get('charset'), style = 'width: 300px') %]</td>
173    </tr>
174
175    <tr>
176     <th align="right">[%- LxERP.t8('Separator') %]:</th>
177     [% SET custom_sep_char = SELF.sep_char %]
178     [% FOREACH entry = SELF.all_sep_chars %]
179      <td>
180       [% IF SELF.sep_char == entry.first %] [% SET custom_sep_char = '' %] [%- END %]
181       [% L.radio_button_tag('sep_char', value => entry.first, label => entry.last, checked => SELF.sep_char == entry.first) %]
182      </td>
183     [%- END %]
184
185     <td>
186      [% L.radio_button_tag('sep_char', value => 'custom', checked => custom_sep_char != '') %]
187      [% L.input_tag('custom_sep_char', custom_sep_char, size => 3, maxlength => 1) %]
188     </td>
189    </tr>
190
191    <tr>
192     <th align="right">[%- LxERP.t8('Quote character') %]:</th>
193     [% SET custom_quote_char = SELF.quote_char %]
194     [% FOREACH entry = SELF.all_quote_chars %]
195      <td>
196       [% IF SELF.quote_char == entry.first %] [% SET custom_quote_char = '' %] [%- END %]
197       [% L.radio_button_tag('quote_char', value => entry.first, label => entry.last, checked => SELF.quote_char == entry.first) %]
198      </td>
199     [%- END %]
200
201     <td>
202      [% L.radio_button_tag('quote_char', value => 'custom', checked => custom_quote_char != '') %]
203      [% L.input_tag('custom_quote_char', custom_quote_char, size => 3, maxlength => 1) %]
204     </td>
205    </tr>
206
207    <tr>
208     <th align="right">[%- LxERP.t8('Escape character') %]:</th>
209     [% SET custom_escape_char = SELF.escape_char %]
210     [% FOREACH entry = SELF.all_escape_chars %]
211      <td>
212       [% IF SELF.escape_char == entry.first %] [% SET custom_escape_char = '' %] [%- END %]
213       [% L.radio_button_tag('escape_char', value => entry.first, label => entry.last, checked => SELF.escape_char == entry.first) %]
214      </td>
215     [%- END %]
216
217     <td>
218      [% L.radio_button_tag('escape_char', value => 'custom', checked => custom_escape_char != '') %]
219      [% L.input_tag('custom_escape_char', custom_escape_char, size => 3, maxlength => 1) %]
220     </td>
221    </tr>
222
223    [% duplicate_fields = SELF.worker.get_duplicate_check_fields() %]
224    [% IF ( duplicate_fields.size ) %]
225      <tr>
226        <th align="right">[%- LxERP.t8('Check for duplicates') %]:</th>
227
228        <td colspan=10>
229          [% FOREACH key = duplicate_fields.keys %]
230            <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 %]>
231            <label for="settings.duplicates_[% key | html %]">[% duplicate_fields.$key.label | html %]</label>
232          [% END %]
233        </td>
234      </tr>
235
236      <tr>
237        <th align="right"></th>
238
239        <td colspan=10>
240          [% opts = [ [ 'no_check',  LxERP.t8('Do not check for duplicates') ],
241                      [ 'check_csv', LxERP.t8('Discard duplicate entries in CSV file') ],
242                      [ 'check_db',  LxERP.t8('Discard entries with duplicates in database or CSV file') ] ] %]
243          [% L.select_tag('settings.duplicates', opts, default = SELF.profile.get('duplicates'), style = 'width: 300px') %]
244        </td>
245      </tr>
246    [% END %]
247
248 [%- IF SELF.type == 'parts' %]
249  [%- INCLUDE 'csv_import/_form_parts.html' %]
250 [%- ELSIF SELF.type == 'customers_vendors' %]
251  [%- INCLUDE 'csv_import/_form_customers_vendors.html' %]
252 [%- ELSIF SELF.type == 'contacts' %]
253  [%- INCLUDE 'csv_import/_form_contacts.html' %]
254 [%- ELSIF SELF.type == 'orders' %]
255  [%- INCLUDE 'csv_import/_form_orders.html' %]
256 [%- END %]
257
258    <tr>
259     <th align="right">[%- LxERP.t8('Preview Mode') %]:</th>
260     <td colspan="10">
261       [% L.radio_button_tag('settings.full_preview', value=2, checked=SELF.profile.get('full_preview')==2, label=LxERP.t8('Full Preview')) %]
262       [% L.radio_button_tag('settings.full_preview', value=1, checked=SELF.profile.get('full_preview')==1, label=LxERP.t8('Only Warnings and Errors')) %]
263       [% L.radio_button_tag('settings.full_preview', value=0, checked=!SELF.profile.get('full_preview'),   label=LxERP.t8('First 20 Lines')) %]
264     </td>
265    </tr>
266
267    <tr>
268     <th align="right">[%- LxERP.t8('Import file') %]:</th>
269     <td colspan="10">[% L.input_tag('file', '', type => 'file', accept => '*') %]</td>
270    </tr>
271
272    [%- IF SELF.file.exists %]
273     <tr>
274      <th align="right">[%- LxERP.t8('Existing file on server') %]:</th>
275      <td colspan="10">[%- LxERP.t8('Uploaded on #1, size #2 kB', SELF.file.displayable_mtime, LxERP.format_amount(SELF.file.size / 1024, 2)) %]</td>
276     </tr>
277    [%- END %]
278
279   </table>
280
281   </div>
282   <hr>
283
284   [% L.submit_tag('action_test', LxERP.t8('Test and preview')) %]
285   [% L.submit_tag('action_import', LxERP.t8('Import'), style='display:none') %]
286
287  </form>
288
289  <div id='results'>
290  [%- IF SELF.deferred %]
291    [%- PROCESS 'csv_import/_deferred_results.html' %]
292  [%- ELSIF SELF.import_status %]
293    [%- PROCESS 'csv_import/_results.html' %]
294  [%- END %]
295  </div>
296
297
298  <script type="text/javascript">
299   <!--
300     $(document).ready(function() {
301       $('#action_save').click(function() {
302         if ($('#profile_name').val() != '')
303           return true;
304         alert('[% LxERP.t8('Please enter a profile name.') %]');
305         return false;
306       })
307     });
308     -->
309  </script>