Multimag  0.2.992
doc.realizaciya.php
См. документацию.
1 <?php
2 // MultiMag v0.2 - Complex sales system
3 //
4 // Copyright (C) 2005-2018, BlackLight, TND Team, http://tndproject.org
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Affero General Public License as
8 // published by the Free Software Foundation, either version 3 of the
9 // License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Affero General Public License for more details.
15 //
16 // You should have received a copy of the GNU Affero General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 
24 
25  function __construct($doc = 0) {
26  parent::__construct($doc);
27  $this->doc_type = 2;
28  $this->typename = 'realizaciya';
29  $this->viewname = 'Реализация товара';
30  $this->sklad_editor_enable = true;
31  $this->header_fields = 'bank sklad cena separator agent';
32  $this->status_list = array(
33  'readytomake' => 'Готов к сборке',
34  'in_process' => 'В процессе сборки',
35  'readytoship' => 'Собран и готов к отгрузке',
36  'courier'=>'Передан курьеру',
37  'err' => 'Ошибочный',
38  'shipped'=>'Отгружен'
39  );
40  }
41 
43  protected function getAdditionalButtonsHTML() {
44  return "<a href='' onclick=\"ShowPopupWin('/doc.php?mode=srv&amp;opt=dov&amp;doc={$this->id}');"
45  . " return false;\" title='Доверенное лицо'><img src='/img/i_users.png' alt='users'></a>".
46  "<a href='' onclick=\"deliveryMenu(event, '{$this->id}'); "
47  . " return false;\" title='Пометить отправленным'><img src='/img/i_ship.png' alt='users'></a>";
48  }
49 
50  function initDefDopdata() {
51  $this->def_dop_data = array('platelshik' => 0, 'gruzop' => 0, 'status' => '', 'kladovshik' => 0,
52  'mest' => '', 'received' => 0, 'return' => 0, 'cena' => 0, 'dov_agent' => 0, 'dov' => '', 'dov_data' => '',
53  'buyer_rname' => '',
54  'cc_name' => '', 'cc_num' => '', 'cc_price' => '', 'cc_date' => '', 'cc_volume'=>'', 'cc_mass'=>'', );
55  }
56 
57  // Создать документ с товарными остатками на основе другого документа
58  public function createFromP($doc_obj) {
59  parent::CreateFromP($doc_obj);
60  $this->setDopData('platelshik', $doc_obj->doc_data['agent']);
61  $this->setDopData('gruzop', $doc_obj->doc_data['agent']);
62  unset($this->doc_data);
63  $this->get_docdata();
64  return $this->id;
65  }
66 
67  public function getExtControls() {
68  return $this->ext_controls = array(
69  'platelshik' => [
70  'type' => 'InputSelector',
71  'label' => 'Плательщик',
72  'data_source' => 'agent.shortlist'
73  ],
74  'gruzop' => [
75  'type' => 'InputSelector',
76  'label' => 'Грузополучатель',
77  'data_source' => 'agent.shortlist'
78  ],
79  'zinfo' => [
80  'type' => 'zinfo',
81  'label' => 'Информация о заявке интернет-магазина',
82  ],
83  'firm_kladovshik_id' => [
84  'type' => 'select',
85  'label' => 'Кладовщик',
86  'data_source' => 'worker.listnames',
87  ],
88  'mest' => [
89  'type' => 'text',
90  'label' => 'Количество мест',
91  ],
92  'received' => [
93  'type' => 'checkbox',
94  'label' => 'Документы подписаны и получены'
95  ],
96  'return' => [
97  'type' => 'checkbox',
98  'label' => 'Возвратный документ'
99  ],
100  );
101  }
102 
103  function DopHead() {
104  global $tmpl, $db;
105 
106  $cur_agent = $this->doc_data['agent'];
107  if (!$cur_agent) {
108  $cur_agent = 1;
109  }
110  $klad_id = @$this->dop_data['kladovshik'];
111  if (!$klad_id) {
112  $klad_id = $this->firm_vars['firm_kladovshik_id'];
113  }
114 
115  $plat_data = $db->selectRow('doc_agent', $this->dop_data['platelshik']);
116  $plat_name = $plat_data ? html_out($plat_data['name']) : '';
117 
118  $gruzop_data = $db->selectRow('doc_agent', $this->dop_data['gruzop']);
119  $gruzop_name = $gruzop_data ? html_out($gruzop_data['name']) : '';
120 
121  $tmpl->addContent("<script type='text/javascript' src='/css/jquery/jquery.autocomplete.js'></script>
122  Плательщик:<br>
123  <input type='hidden' name='plat_id' id='plat_id' value='{$this->dop_data['platelshik']}'>
124  <input type='text' id='plat' style='width: 100%;' value='$plat_name'><br>
125  Грузополучатель:<br>
126  <input type='hidden' name='gruzop_id' id='gruzop_id' value='{$this->dop_data['gruzop']}'>
127  <input type='text' id='gruzop' style='width: 100%;' value='$gruzop_name'><br>
128  Кладовщик:<br><select name='kladovshik'>
129  <option value='0'>--не выбран--</option>");
130 
131  $res = $db->query("SELECT `user_id`, `worker_real_name` FROM `users_worker_info` WHERE `worker`='1' ORDER BY `worker_real_name`");
132  while ($nxt = $res->fetch_row()) {
133  $s = ($klad_id == $nxt[0]) ? 'selected' : '';
134  $tmpl->addContent("<option value='$nxt[0]' $s>" . html_out($nxt[1]) . "</option>");
135  }
136  $tmpl->addContent("</select><br>
137  Количество мест:<br>
138  <input type='text' name='mest' value='{$this->dop_data['mest']}'><br><hr>");
139  if($this->doc_data['p_doc']) {
140  $parent_doc = \document::getInstanceFromDb($this->doc_data['p_doc']);
141  if($parent_doc->typename=='zayavka') {
142  if ($parent_doc->dop_data['ishop']) {
143  $tmpl->addContent("<b>К заявке с интернет-витрины</b><br>");
144  }
145  if ($parent_doc->dop_data['buyer_rname']) {
146  $tmpl->addContent("<b>ФИО: </b>{$this->dop_data['buyer_rname']}<br>");
147  }
148  if ($parent_doc->dop_data['pay_type']) {
149  $tmpl->addContent("<b>Способ оплаты: </b>");
150  switch ($parent_doc->dop_data['pay_type']) {
151  case 'bank': $tmpl->addContent("безналичный");
152  break;
153  case 'cash': $tmpl->addContent("наличными");
154  break;
155  case 'card': $tmpl->addContent("картой ?");
156  break;
157  case 'card_o': $tmpl->addContent("картой на сайте");
158  break;
159  case 'card_t': $tmpl->addContent("картой при получении");
160  break;
161  case 'wmr': $tmpl->addContent("Webmoney WMR");
162  break;
163  default: $tmpl->addContent("не определён ({$this->dop_data['pay_type']})");
164  }
165  $tmpl->addContent("<br>");
166  }
167  if($parent_doc->dop_data['buyer_email']) {
168  $tmpl->addContent("<b>e-mail, прикреплённый к заявке:</b> ".html_out($parent_doc->dop_data['buyer_email'])."<br>");
169  }
170  if($parent_doc->dop_data['buyer_phone']) {
171  $tmpl->addContent("<b>Телефон, прикреплённый к заявке:</b> ".html_out($parent_doc->dop_data['buyer_phone'])."<br>");
172  }
173  if($parent_doc->dop_data['delivery']) {
174  $tmpl->addContent("<b>Доставка:</b>");
175  $res = $db->query("SELECT `id`, `name` FROM `delivery_types` ORDER BY `id`");
176  while ($nxt = $res->fetch_row()) {
177  if ($nxt[0] == $parent_doc->dop_data['delivery']) {
178  $tmpl->addContent(html_out($nxt[1]));
179  }
180  }
181  $tmpl->addContent("<br>");
182  }
183  if($parent_doc->dop_data['delivery_region']) {
184  $tmpl->addContent("<b>Регион доставки:</b>");
185  $res = $db->query("SELECT `id`, `name` FROM `delivery_regions` ORDER BY `id`");
186  while ($nxt = $res->fetch_row()) {
187  if ($nxt[0] == $parent_doc->dop_data['delivery_region']) {
188  $tmpl->addContent(html_out($nxt[1]));
189  }
190  }
191  $tmpl->addContent("<br>");
192  }
193  if($parent_doc->dop_data['delivery_date']) {
194  $tmpl->addContent("<b>Желаемая дата доставки: </b>".html_out($parent_doc->dop_data['delivery_date'])."<br>");
195  }
196  if ($parent_doc->dop_data['delivery_address']) {
197  $tmpl->addContent("<b>Адрес доставки: </b>{$parent_doc->dop_data['delivery_address']}<br>");
198  }
199  $tmpl->addContent("<hr>");
200  }
201  }
202 
203  $tmpl->addContent("Статус:<br>
204  <select name='status'>");
205  if ($this->dop_data['status'] == '') {
206  $tmpl->addContent("<option value=''>Не задан</option>");
207  }
208  foreach ($this->status_list as $id => $name) {
209  $s = (@$this->dop_data['status'] == $id) ? 'selected' : '';
210  $tmpl->addContent("<option value='$id' $s>" . html_out($name) . "</option>");
211  }
212 
213  $tmpl->addContent("</select><br>
214 
215  <script type=\"text/javascript\">
216  $(document).ready(function(){
217  $(\"#plat\").autocomplete(\"/docs.php\", {
218  delay:300,
219  minChars:1,
220  matchSubset:1,
221  autoFill:false,
222  selectFirst:true,
223  matchContains:1,
224  cacheLength:10,
225  maxItemsToShow:15,
226  formatItem:agliFormat,
227  onItemSelect:platselectItem,
228  extraParams:{'l':'agent','mode':'srv','opt':'ac'}
229  });
230  $(\"#gruzop\").autocomplete(\"/docs.php\", {
231  delay:300,
232  minChars:1,
233  matchSubset:1,
234  autoFill:false,
235  selectFirst:true,
236  matchContains:1,
237  cacheLength:10,
238  maxItemsToShow:15,
239  formatItem:agliFormat,
240  onItemSelect:gruzopselectItem,
241  extraParams:{'l':'agent','mode':'srv','opt':'ac'}
242  });
243  });
244 
245  function platselectItem(li) {
246  if( li == null ) var sValue = \"Ничего не выбрано!\";
247  if( !!li.extra ) var sValue = li.extra[0];
248  else var sValue = li.selectValue;
249  document.getElementById('plat_id').value=sValue;
250  }
251 
252  function gruzopselectItem(li) {
253  if( li == null ) var sValue = \"Ничего не выбрано!\";
254  if( !!li.extra ) var sValue = li.extra[0];
255  else var sValue = li.selectValue;
256  document.getElementById('gruzop_id').value=sValue;
257  }
258  </script>
259  ");
260 
261  $checked_r = $this->dop_data['received'] ? 'checked' : '';
262  $tmpl->addContent("<label><input type='checkbox' name='received' value='1' $checked_r>Документы подписаны и получены</label><br>");
263  $checked = $this->dop_data['return'] ? 'checked' : '';
264  $tmpl->addContent("<label><input type='checkbox' name='return' value='1' $checked>Возвратный документ</label><br>");
265  }
266 
267  function DopSave() {
268  $new_data = array(
269  'status' => request('status'),
270  'kladovshik' => rcvint('kladovshik'),
271  'platelshik' => rcvint('plat_id'),
272  'gruzop' => rcvint('gruzop_id'),
273  'received' => request('received') ? '1' : '0',
274  'return' => request('return') ? '1' : '0',
275  'mest' => rcvint('mest')
276  );
277  $old_data = array_intersect_key($new_data, $this->dop_data);
278  if ($this->id && @$old_data['status'] != $new_data['status']) {
279  $this->sentZEvent('cstatus:' . $new_data['status']);
280  }
281  $this->setDopDataA($new_data);
282  }
283 
284  function dopBody() {
285  global $tmpl;
286  if ($this->dop_data['received']) {
287  $tmpl->addContent("<br><b>Документы подписаны и получены</b><br>");
288  }
289  }
290 
292  public function extendedApplyAclCheck() {
293  $acl_obj = ['store.global', 'store.'.$this->doc_data['sklad']];
294  if (!\acl::testAccess($acl_obj, \acl::APPLY)) {
295  $d_start = date_day(time());
296  $d_end = $d_start + 60 * 60 * 24 - 1;
297  if (!\acl::testAccess($acl_obj, \acl::TODAY_APPLY)) {
298  throw new \AccessException('Не достаточно привилегий для проведения документа с выбранным складом '.$this->doc_data['sklad']);
299  } elseif ($this->doc_data['date'] < $d_start || $this->doc_data['date'] > $d_end) {
300  throw new \AccessException('Не достаточно привилегий для проведения документа с выбранным складом '.$this->doc_data['sklad'].' произвольной датой');
301  }
302  }
303  parent::extendedApplyAclCheck();
304  }
305 
307  public function extendedCancelAclCheck() {
308  $acl_obj = ['store.global', 'store.'.$this->doc_data['sklad']];
309  if (!\acl::testAccess($acl_obj, \acl::CANCEL)) {
310  $d_start = date_day(time());
311  $d_end = $d_start + 60 * 60 * 24 - 1;
312  if (!\acl::testAccess($acl_obj, \acl::TODAY_CANCEL)) {
313  throw new \AccessException('Не достаточно привилегий для отмены проведения документа с выбранным складом '.$this->doc_data['sklad']);
314  } elseif ($this->doc_data['date'] < $d_start || $this->doc_data['date'] > $d_end) {
315  throw new \AccessException('Не достаточно привилегий для отмены проведения документа с выбранным складом '.$this->doc_data['sklad'].' произвольной датой');
316  }
317  }
318  parent::extendedCancelAclCheck();
319  }
320 
322  function docApply($silent = 0) {
323  global $CONFIG, $db;
324  if(!$this->isAltNumUnique() && !$silent) {
325  throw new Exception("Номер документа не уникален!");
326  }
327  $tim = time();
328  $res = $db->query("SELECT `doc_list`.`id`, `doc_list`.`date`, `doc_list`.`type`, `doc_list`.`sklad`, `doc_list`.`ok`, `doc_list`.`firm_id`,
329  `doc_sklady`.`dnc`, `doc_sklady`.`firm_id` AS `store_firm_id`, `doc_agent`.`no_bonuses`, `doc_vars`.`firm_store_lock`, `doc_list`.`p_doc`
330  FROM `doc_list`
331  INNER JOIN `doc_sklady` ON `doc_sklady`.`id`=`doc_list`.`sklad`
332  INNER JOIN `doc_agent` ON `doc_list`.`agent` = `doc_agent`.`id`
333  INNER JOIN `doc_vars` ON `doc_list`.`firm_id` = `doc_vars`.`id`
334  WHERE `doc_list`.`id`='{$this->id}'");
335  $doc_params = $res->fetch_assoc();
336  $res->free();
337  if ($doc_params['ok'] && (!$silent)) {
338  throw new Exception('Документ уже был проведён!');
339  }
340  if (!$this->dop_data['kladovshik'] && @$CONFIG['doc']['require_storekeeper'] && !$silent) {
341  throw new Exception("Кладовщик не выбран!");
342  }
343  if (!$this->dop_data['mest'] && @$CONFIG['doc']['require_pack_count'] && !$silent) {
344  throw new Exception("Количество мест не задано");
345  }
346  // Запрет на списание со склада другой фирмы
347  if($doc_params['store_firm_id']!=null && $doc_params['store_firm_id']!=$doc_params['firm_id']) {
348  throw new Exception("Выбранный склад принадлежит другой организации!");
349  }
350  // Ограничение фирмы списком своих складов
351  if($doc_params['firm_store_lock'] && $doc_params['store_firm_id']!=$doc_params['firm_id']) {
352  throw new Exception("Выбранная организация может списывать только со своих складов!!");
353  }
354 
355  if (!$silent) {
356  $this->sentZEvent('pre-apply'); // В т.ч. для обсчёта резервов
357  $ok_time = time();
358  $db->update('doc_list', $this->id, 'ok', $ok_time);
359  $this->doc_data['ok'] = $ok_time;
360  }
361 
362  $res = $db->query("SELECT `doc_list_pos`.`tovar`, `doc_list_pos`.`cnt`, `doc_base_cnt`.`cnt`, `doc_base`.`name`, `doc_base`.`proizv`,
363  `doc_base`.`pos_type`, `doc_list_pos`.`id`, `doc_base`.`vc`, `doc_list_pos`.`cost`
364  FROM `doc_list_pos`
365  LEFT JOIN `doc_base` ON `doc_base`.`id`=`doc_list_pos`.`tovar`
366  LEFT JOIN `doc_base_cnt` ON `doc_base_cnt`.`id`=`doc_base`.`id` AND `doc_base_cnt`.`sklad`='{$doc_params['sklad']}'
367  WHERE `doc_list_pos`.`doc`='{$this->id}' AND `doc_base`.`pos_type`='0'");
368  $bonus = 0;
369  $fail_text = '';
370  while ($nxt = $res->fetch_row()) {
371  if (!$doc_params['dnc']) {
372  if ($nxt[1] > $nxt[2]) {
373  $pos_name = composePosNameStr($nxt[0], $nxt[7], $nxt[3], $nxt[4]);
374  $fail_text .= " - Мало товара '$pos_name' - есть:{$nxt[2]}, нужно:{$nxt[1]}. \n";
375  continue;
376  }
377  }
378 
379  $db->query("UPDATE `doc_base_cnt` SET `cnt`=`cnt`-'$nxt[1]' WHERE `id`='$nxt[0]' AND `sklad`='{$doc_params['sklad']}'");
380 
381  if (!$doc_params['dnc'] && (!$silent)) {
382  $ret = getStoreCntOnDate($nxt[0], $doc_params['sklad'], $doc_params['date'], false, true);
383  if ($ret['cnt'] < 0) {
384  $pos_name = composePosNameStr($nxt[0], $nxt[7], $nxt[3], $nxt[4]);
385  $fail_text .= " - Будет ({$ret['cnt']}) мало товара '$pos_name', документ {$ret['doc']} \n";
386  continue;
387  }
388  }
389 
390  if (\cfg::get('poseditor', 'sn_restrict')) {
391  $r = $db->query("SELECT COUNT(`doc_list_sn`.`id`) FROM `doc_list_sn` WHERE `rasx_list_pos`='$nxt[6]'");
392  list($sn_cnt) = $r->fetch_row();
393  if ($sn_cnt != $nxt[1]) {
394  $pos_name = composePosNameStr($nxt[0], $nxt[7], $nxt[3], $nxt[4]);
395  $fail_text .= " - Мало серийных номеров товара '$pos_name' - есть:$sn_cnt, нужно:{$nxt[1]}. \n";
396  continue;
397  }
398  }
399  $bonus+=$nxt[8] * $nxt[1] * \cfg::get('bonus', 'coeff', 0);
400  }
401  if($fail_text) {
402  throw new Exception("Ошибка в номенклатуре: \n".$fail_text);
403  }
404  if ($silent) {
405  return;
406  }
407  $this->fixPrice();
408 
409  if (!$doc_params['no_bonuses'] && $bonus > 0) {
410  $db->query("REPLACE INTO `doc_dopdata` (`doc`,`param`,`value`) VALUES ( '{$this->id}' ,'bonus','$bonus')");
411  }
412 
413  $this->sentZEvent('apply');
414  }
415 
416  function docCancel() {
417  global $db;
418 
419  $res = $db->query("SELECT `doc_list`.`id`, `doc_list`.`date`, `doc_list`.`type`, `doc_list`.`sklad`, `doc_list`.`ok`
420  FROM `doc_list` WHERE `doc_list`.`id`='{$this->id}'");
421  if (!$res->num_rows) {
422  throw new Exception('Документ не найден!');
423  }
424  $nx = $res->fetch_row();
425  if (!$nx[4]) {
426  throw new Exception('Документ НЕ проведён!');
427  }
428  $res = $db->query("SELECT `id` FROM `doc_list` WHERE `p_doc`='{$this->id}' AND `ok`>'0'");
429  if ($res->num_rows) {
430  throw new Exception('Нельзя отменять документ с проведёнными подчинёнными документами.');
431  }
432 
433  $this->sentZEvent('pre-cancel'); // В т.ч. для обсчёта резервов
434  $db->update('doc_list', $this->id, 'ok', 0);
435  $this->doc_data['ok'] = 0;
436 
437  $res = $db->query("SELECT `doc_list_pos`.`tovar`, `doc_list_pos`.`cnt`, `doc_base`.`pos_type` FROM `doc_list_pos`
438  LEFT JOIN `doc_base` ON `doc_base`.`id`=`doc_list_pos`.`tovar` WHERE `doc_list_pos`.`doc`='{$this->id}' AND `doc_base`.`pos_type`='0'");
439  while ($nxt = $res->fetch_row()) {
440  $db->query("UPDATE `doc_base_cnt` SET `cnt`=`cnt`+'$nxt[1]' WHERE `id`='$nxt[0]' AND `sklad`='$nx[3]'");
441  }
442  $db->query("REPLACE INTO `doc_dopdata` (`doc`,`param`,`value`) VALUES ( '{$this->id}' ,'bonus','0')");
443 
444  $this->sentZEvent('cancel');
445  }
446 
451  public function getMorphList() {
452  $morphs = array(
453  'permitout' => ['name'=>'permitout', 'document' => 'permitout', 'viewname' => 'Пропуск на вывоз', ],
454  'pbank' => ['name'=>'pbank', 'document' => 'pbank', 'viewname' => 'Приходный банковский ордер', ],
455  'pko' => ['name'=>'pko', 'document' => 'pko', 'viewname' => 'Приходный кассовый ордер', ],
456  'payinfo' => ['name'=>'payinfo', 'document' => 'payinfo', 'viewname' => 'Информация о безналичном платеже', ],
457  'kordolga' => ['name'=>'kordolga', 'document' => 'kordolga', 'viewname' => 'Корректировка долга', ],
458  );
459  if (!$this->doc_data['p_doc']) {
460  $morphs['zayavka'] = ['name'=>'zayavka', 'document' => 'zayavka', 'viewname' => 'Заявка (родительская)', ];
461  }
462  return $morphs;
463  }
464 
470  protected function morphTo_zayavka() {
471  if($this->doc_data['p_doc']) {
472  throw new Exception('У документа уже есть основание.');
473  }
474  $new_doc = new \doc_Zayavka();
475  $dd = $new_doc->CreateParent($this);
476  $new_doc->setDopData('cena', $this->dop_data['cena']);
477  $this->setDocData('p_doc', $dd);
478  return $new_doc;
479  }
480 
485  protected function morphTo_pko() {
486 
487  $this->recalcSum();
488  $new_doc = new \doc_Pko();
489  $new_doc->createFrom($this);
491  $new_doc->setDocData('kassa', $pref->getSitePref('site_cash_id'));
492  $codename = $this->getDopData('return')?'goods_return':'goods_sell';
493  $new_doc->setCreditTypeFromCodename($codename);
494  return $new_doc;
495  }
496 
501  protected function morphTo_payinfo() {
502 
503  $this->recalcSum();
504  $new_doc = new \doc_PayInfo();
505  $new_doc->createFrom($this);
507  $new_doc->setDocData('bank', $this->getDocData('bank'));
508  return $new_doc;
509  }
510 
515  protected function morphTo_pbank() {
516  $this->recalcSum();
517  $new_doc = new \doc_Pbank();
518  $new_doc->createFrom($this);
520  $new_doc->setDocData('bank', $pref->getSitePref('site_bank_id'));
521  $codename = $this->getDopData('return')?'goods_return':'goods_sell';
522  $new_doc->setCreditTypeFromCodename($codename);
523  return $new_doc;
524  }
525 
530  protected function morphTo_kordolga() {
531  $this->recalcSum();
532  $new_doc = new \doc_Kordolga();
533  $new_doc->createFrom($this);
534  $new_doc->setDocData('sum', $this->doc_data['sum'] * (-1));
535  return $new_doc;
536  }
537 
542  protected function morphTo_permitout() {
543  $this->recalcSum();
544  $new_doc = new \doc_PermitOut();
545  $new_doc->createFrom($this);
546  return $new_doc;
547  }
548 
549  protected function getDovForm() {
550  global $db;
551  $info = $db->selectRowA('doc_agent_dov', $this->dop_data['dov_agent'], array('name', 'surname'));
552  $agn = '';
553  if ($info['name']) {
554  $agn = $info['name'];
555  }
556  if ($info['surname']) {
557  if ($agn) {
558  $agn.=' ';
559  }
560  $agn.=$info['surname'];
561  }
562 
563  return "<form method='post' action=''>
564 <input type=hidden name='mode' value='srv'>
565 <input type=hidden name='opt' value='dovs'>
566 <input type=hidden name='doc' value='{$this->id}'>
567 <table>
568 <tr><th>Доверенное лицо (<a href='docs.php?l=dov&mode=edit&ag_id={$this->doc_data['agent']}' title='Добавить'><img border=0 src='img/i_add.png' alt='add'></a>)
569 <tr><td><input type=hidden name=dov_agent value='" . $this->dop_data['dov_agent'] . "' id='sid' ><input type=text id='sdata' value='$agn' onkeydown=\"return RequestData('/docs.php?l=dov&mode=srv&opt=popup&ag={$this->doc_data['agent']}')\">
570  <div id='popup'></div>
571  <div id=status></div>
572 
573 <tr><th class=mini>Номер доверенности
574 <tr><td><input type=text name=dov value='" . $this->dop_data['dov'] . "' class=text>
575 
576 <tr><th>Дата выдачи
577 <tr><td>
578 <p class='datetime'>
579 <input type=text name=dov_data value='" . $this->dop_data['dov_data'] . "' id='id_pub_date_date' class='vDateField required text' >
580 </p>
581 
582 </table>
583 <input type=submit value='Сохранить'></form>";
584  }
585 
586  public function Service() {
587  global $tmpl;
588 
589  $tmpl->ajax = 1;
590  $opt = request('opt');
591  $pos = request('pos');
592 
593  switch($opt) {
594  case 'selfship':
595  \acl::accessGuard('doc.'.$this->typename, \acl::UPDATE);
596  $this->setDopData('status', 'shipped');
597  $this->sentZEvent('selfship');
598  $ret = array(
599  'response' => 'selfship ',
600  'status' => 'ok',
601  );
602  $tmpl->setContent(json_encode($ret, JSON_UNESCAPED_UNICODE));
603  return true;
604  case 'ship_info':
605  \acl::accessGuard('doc.'.$this->typename, \acl::VIEW);
606  $tmpl->ajax = true;
607  $ret = array(
608  'response' => 'ship_info',
609  'status' => 'ok',
610  'name' => $this->dop_data['cc_name'],
611  'num' => $this->dop_data['cc_num'],
612  'price' => $this->dop_data['cc_price'],
613  'date' => $this->dop_data['cc_date'],
614  'volume' => $this->dop_data['cc_volume'],
615  'mass' => $this->dop_data['cc_mass'],
616  );
617  $tmpl->setContent(json_encode($ret, JSON_UNESCAPED_UNICODE));
618  return true;
619  case 'ship_enter':
620  \acl::accessGuard('doc.'.$this->typename, \acl::UPDATE);
621  $cc_info = array(
622  'cc_name' => request('cc_name'),
623  'cc_num' => request('cc_num'),
624  'cc_date' => rcvdate('cc_date'),
625  'cc_price' => rcvrounded('cc_price', 2),
626  'status' => 'shipped'
627  );
628  $this->setDopDataA($cc_info);
629  $this->sentZEvent('shipped');
630  $ret = array(
631  'response' => 'ship_enter',
632  'status' => 'ok',
633  );
634  $tmpl->setContent(json_encode($ret, JSON_UNESCAPED_UNICODE));
635  return true;
636  }
637 
638  if (parent::_Service($opt, $pos)) {
639  return true;
640  }
641 
642  switch($opt) {
643  case 'dov':
644  $tmpl->setContent( $this->getDovForm() );
645  return true;
646  case 'dovs':
647  \acl::accessGuard('doc.'.$this->typename, \acl::UPDATE);
648  $data = array(
649  'dov' => request('dov'),
650  'dov_agent' => request('dov_agent'),
651  'dov_data' => request('dov_data'),
652  );
653  $this->setDopDataA($data);
654  redirect("/doc.php?mode=body&doc={$this->id}");
655  return true;
656  default:
657  throw new \NotFoundException("Неизвестная опция $opt!");
658  }
659  }
660 }
setDocData($name, $value)
Установить основной параметр документа
Definition: document.php:240
$res
Definition: fixer.php:178
rcvint($varname, $def=0)
Безопасное получение целого значения
Definition: core.php:208
getDopData($name)
Получить значение дополнительного параметра документа. Вернёт пустую строку в случае отсутствия парам...
Definition: document.php:292
static getInstance()
Definition: pref.php:70
Документ *Реализация*.
$pref
Definition: counter.php:49
extendedApplyAclCheck()
Выполнение дополнительных проверок доступа для проведения документа
html_out($data)
Обёртка над htmlentities.
Definition: core.php:249
createFromP($doc_obj)
composePosNameStr($id=0, $vc= '', $name= '', $vendor= '')
Сформировать строку с названием элемента списка номенклатуры в зависимости от настроек Если какой-то ...
Definition: doc.core.php:296
request($varname, $def='')
Definition: core.php:190
const TODAY_CANCEL
Отмена проведения / остановка текущим днём
Definition: acl.php:34
rcvdate($varname, $def='1970-01-01')
Безопасное получение строки с датой
Definition: core.php:222
Базовый класс для всех документов системы. Содержит основные методы для работы с документами.
sentZEvent($event_type)
const VIEW
Просмотр
Definition: acl.php:26
static getInstanceFromDb($doc_id)
Definition: document.php:146
$s
Definition: price_an.php:409
getAdditionalButtonsHTML()
Получить строку с HTML кодом дополнительных кнопок документа
$db
$tim
Definition: resp_clear.php:27
static testAccess($object, $flags, $no_redirect=false)
Definition: acl.php:173
static accessGuard($object, $flags, $no_redirect=false)
То же, что и testAccess, но бросает исключение, если нет доступа
Definition: acl.php:213
getStoreCntOnDate($pos_id, $store_id, $unixtime=null, $noBreakIfMinus=0, $extinfo=false)
Definition: doc.core.php:515
const APPLY
Проведение / запуск
Definition: acl.php:31
$tmpl
setDopDataA($array)
Установить дополнительные данные текущего документа
Definition: document.php:327
isAltNumUnique()
Проверка уникальности альтернативного порядкового номера документа
const TODAY_APPLY
Проведение / запуск текущим днём
Definition: acl.php:33
$data
Definition: api.php:27
rcvrounded($varname, $round=3, $def=0)
Безопасное получение числа заданной точности
Definition: core.php:215
date_day($date)
const CANCEL
Отмена проведения / остановка
Definition: acl.php:32
$opt
Definition: adm.php:65
$doc
Definition: doc.php:28
const UPDATE
Обновление
Definition: acl.php:28
static get($sect, $param, $default=null)
Definition: cfg.php:46
setDopData($name, $value)
Definition: document.php:310
$r
Definition: keygen.php:23
$id
ID документа
Definition: document.php:23
redirect($url)
Отсылает заголовок перенаправления в броузер и завершает скрипт
Definition: core.php:118
extendedCancelAclCheck()
Выполнение дополнительных проверок доступа для отмены документа
$CONFIG['site']['admin_name']
docApply($silent=0)
Провести документ
fixPrice()
Зафиксировать цену документа, если она установлена в *авто*. Выполняется при проведении некоторых тип...
getDocData($name)
Получить значение основного параметра документа. Вернёт пустую строку в случае отсутствия параметра ...
Definition: document.php:226