Въвеждането на информацията за изработеното от работниците трябва да се извършва своевременно и това може да се осъществи, както с интерактивните средства на модул Производство, така и чрез разработените Web services в Colibri® ERP, свързани с модула за производство.
Използването на web seрvices позволява контрол на аутентикацията и пълна автоматизация на комуникацията между Colibri® ERP и необходимата в случая външна софтуерна система за събиране и натрупване на данните за изработеното от работниците.
Информацията в тази глава е предназначена основно за разработчиците на web services за комуникация с производствения модул на Colibri® ERP.
Процесът е следния:
Информацията за изработеното от работниците се събира от външна система за електронно регистриране на изработеното;
Външната система периодично подава събраната за изработеното информация към Colibri® ERP чрез web service;
Colibri® ERP приема информацията, проверява я за коректност и връща отговор към външната система с информация за приетите данни и информация за откритите грешни записи или несъответствия.
Основната структура от данни, която е необходимо да се подава от външната система е последователност от записи всеки от които е масив със спедните полета:
array( "idOperPersCard" => array("name" => "idOperPersCard", "type" => "xsd:integer") , "CNum" => array("name" => "CNum", "type" => "xsd:string") , "idOper" => array("name" => "idOper", "type" => "xsd:integer") , "ONum" => array("name" => "ONum", "type" => "xsd:string") , "idSector" => array("name" => "idSector", "type" => "xsd:integer") , "SectorNum" => array("name" => "SectorNum", "type" => "xsd:string") , "RefNum" => array("name" => "RefNum", "type" => "xsd:string") , "QuantityOK" => array("name" => "QuantityOK", "type" => "xsd:double") , "QuantityWaste" => array("name" => "QuantityWaste", "type" => "xsd:double") , "QuantityWasteSubj" => array("name" => "QuantityWasteSubj", "type" => "xsd:double") , "CompleteTime" => array("name" => "CompleteTime", "type" => "xsd:string") );
Показаната структура съдържа информация и за типа на всяко от полетата.
Задължителни полета са:
CNum – Номер на производствената карта (ПК) в Colibri® ERP, за която се подава заработка;
Onum – номер на операцията, за която се подава изработено. Номера на операцията е от процеса на производство по рецептурата, използвана в ПК;
SectorNum – номер на работния сектор. Номера на сектора е от процеса на производство по рецептурата, използвана в ПК;
RefNum – референтен номер на изпълнителя, работника. В списъка с работниците съответства на полето Код. Това е общ референтен номер по-който Colibri® ERP и външната система разпознават един и същи работник;
QuantitiOK – брой изпълнения на операция Onum в SectorNum от работника RefNum, отговарящи на критериите за качество;
QuantityWaste - брой изпълнения на операция Onum в SectorNum от работника RefNum, завършили с брак не по вина на работника;
QuantityWasteSubj - брой изпълнения на операция Onum в SectorNum от работника RefNum, завършили с брак по вина на работника;
CompleteTime – време на подаване на операцията, съдържащо дата и час. Тази информация е текст със следния формат „DD.MM.YYYY hh:mm:ss”.
Ето един примерен масив в запитване за изпращане на заработки (PHP код):
$work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "П-002" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "1" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:05" );
Тази е основната функция и е предназначена да импортира заработки от друга система.
Добре е всяка ПК да е с една рецепта (макар да не е задължително)! Това е нормален случай, когато ПК е и маршрутна карта за производството на дадени изделия. В данните лисва номера на рецептата и заработката ще се въведе във всички рецепти от ПК (с номер CNum), в чиито списък с операции и работни центрове присъстват тези от импортирания запис.
Идентификацията се извършва по CNum, ONum, SectorNum, RefNum.
Функцията работи по следния начин:
Първо се проверяват за коректност всички данни;
Ако някой запис не е добре конфигуриран, не се обработва никой от записите;
Ако всички данни са добре конфигурирани, се подреждат по ред на изпълнение (ExecOrder) на операциите и по време на изпълнение (CompleteTume) и тогава се вмъкват в съответната ПК;
Ако някоя ПК (CNum) е приключена, записът за нея се прескача и не се обработва.
Детайлно, работата на функцията е разгледана по-нататък.
Функция за автоматизирано въвеждане и обновяване на списъка с работници от външната система към Colibri® ERP. Структурата на подаваните от външната система данни е следната:
array( "idPersonal" => array("name" => "idPersonal", "type" => "xsd:integer") , "PersNum" => array("name" => "PersNum", "type" => "xsd:string") , "RefNum" => array("name" => "RefNum", "type" => "xsd:string") , "PersName" => array("name" => "PersName", "type" => "xsd:string") , "isActive" => array("name" => "isActive", "type" => "xsd:integer") )
Задължителни полета са:
RefNum – референтен номер на изпълнителя, работника. В списъка с работниците в Colibri® ERP, съответства на полето Код. Това е общ рефернтен номер по-който Colibri® ERP и външната система разпознават един и същи работник;
PersName – име на работника или служителя;
isActive – поле, показващо дали работника ще е активен или не от гледна точка на Colibri® ERP. Стойност 1 за активен, 0 – за неактивен.
Ето един примерен масив в PHP код, който може да бъде подаван от външна система, за да се допълва или модифицира списъка с персонала в Colibri® ERP:
$workman[] = array( "RefNum" => "YYYYY" , "PersName" => "Харалампи Хаджипокарахаралампиев" , "isActive" => "1" );
Ако в списъка с персонала на Colibri® ERP липсва човек с RefNum, посочен в записа, то се добавя нов работник в този списък.
Ако в списъка с персонала на Colibri® ERP вече има човек с RefNum, посочен в записа, се модифицират неговото име в съответствие с PersName, а неговата активност спрямо Colibri® ERP в съответствие със стойността на isActive.
Функцията връща масив от записи, съдържащи данните за наличните в Colibri® ERP операции от списъка с операции, заедно със съответния работен център (сектор).
Структурата на получавания масив е следната:
array( "idOper" => array("name" => "idOper", "type" => "xsd:integer") , "idSector" => array("name" => "idSector", "type" => "xsd:integer") , "ONum" => array("name" => "ONum", "type" => "xsd:string") , "OName" => array("name" => "OName", "type" => "xsd:string") , "SectorNum" => array("name" => "SectorNum", "type" => "xsd:string") , "SectorName" => array("name" => "SectorName", "type" => "xsd:string") )
Където:
ONum - номер на операцията в списъка с операции в Colibri® ERP;
OName – наименование на операцията;
SectorNum – номер на сектор, на който се изпълнява операция ONum;
SectorName – наименование на сектора.
Ето и пример за отговор от Colibri® ERP - масив с данни за операция и сектор:
0 => array ( 'idOper' => 68, 'idSector' => 13, 'ONum' => 'ШЛ', 'OName' => 'Шлайфане', 'SectorNum' => 'У-Ш', 'SectorName' => 'Участък- шлайфане', ), ......... )
Примерен код на PHP извикване на функция GetOperations:
<?php include("nusoap.php"); // Entry point data $WS_URL = "https://dev3.edabg.com/erp/ws/wsbase.php?wsdl"; // Initializing client $sc = new nusoap_client($WS_URL, true); $err = $sc->getError(); if ($err) { echo "Constructor error $err\n"; } $sc->soap_defencoding = "UTF-8"; $sc->decode_utf8 = false; $sc->data_encoding = "UTF-8"; $sc->encode_utf8 = false; // Login използвайки потребител soap който е от тип web service $result = $sc->call("erpSOAPServer..Login", array("username" => "soap", "password" => "123")); echo "Calling ...<br>"; //------------------------------------------------------ // Test for function $result = $sc->call("erpSOAPProd..GetOperations", //------------------------------------------------------ $result = $sc->call("erpSOAPProd..GetOperations"); if ($sc->fault) { echo "Fault:<br>"; echo "<pre>".var_export($result,true)."</pre>"; } else { $err = $sc->getError(); if ($err) { echo "Error: $err<br>"; } else { echo "<pre>".var_export($result,true)."</pre>"; } } //------------------------------------------------------ // End of Test for function $result = $sc->call("erpSOAPProd..GetOperations", //------------------------------------------------------ echo "<hr>Request<br>"; echo "<pre>"._h(var_export($sc->request,true))."</pre>"; echo "<hr>Response<br>"; echo "<pre>"._h(var_export($sc->response,true))."</pre>"; $result = $sc->call("erpSOAPServer..Logout"); ?>
Този web service е предназначен да предаде на външна система за електронно събиране на заработките, списък от тройки ПК-операция-сектор (CNum-ONum-SectorNum), за да бъдат използвани при натрупването на информация за изпълнение по тях.
Функцията връща масив от записи, съдържащи данните за използваните в момента (в производствени карти) операции, заедно със съответния им работен център (сектор). Това са тройки ПК-операция-сектор, които са за производствени карти, които не са приключени.
Отговорът на запитването има следния вид:
array ( 0 => array ( 'CNum' => '0001726', 'idOper' => 72, 'idSector' => 2, 'ONum' => 'П-002', 'OName' => 'Огъване', 'SectorNum' => 'У-002', 'SectorName' => 'Участък за втората операция', 'toDo_max' => 3, 'toDo' => 2, ), 1 => array ( 'CNum' => '0001726', 'idOper' => 71, 'idSector' => 28, 'ONum' => 'П-001', 'OName' => 'Нарязване', 'SectorNum' => 'МТ-005', 'SectorName' => 'Чепорез', 'toDo_max' => 3, 'toDo' => 1, ), ............................ )
Където:
CNum - номер на производствената карта (ПК) в Colibri® ERP;
ONum – номер на операцията в списъка с операции в Colibri® ERP;
OName – наименование на операцията;
SectorNum – номер на сектор, на който се изпълнява операция ONum;
SectorName – наименование на сектора.
В отговора, полетата toDo_max и toDo, показват (в момента на изпълнение на функцията GetActiveOpers), колко бройки системата очаква да се изработят по дадена тройка ПК-операция-Сектор, т.е. колко броя детайли стоят пред дадена операция от даден маршрут (ПК), за да бъдат изпълнени.
По този начин върнатата стойност в полетата toDo_max и toDo може да се използва за контрол на регистрираното от работниците изпълнение във външната система за електронно отчитане на изработеното.
toDo_max (= QtyPlan-QtyBrak-QtyOk) - показва максимално възможния брой изпълнения, които да могат да се регистрират по операцията в дадения маршрут (ПК). Полето е предназначено да се използва за контрол от външната система, ако функцията PutWork се изпълнява през известни интервали от време, например през час или в края на деня, т.е. когато информацията за изработеното идва към Colibri® ERP асинхронно спрямо реалната регистрация на изработки във външната система;
toDo – показва точно колко изделия стоят пред операцията, според регистрираното от последното изпълнение на функцията PutWork. Стойността може да се използва от външни системи за регистриране на заработки, които синхронно подават информацията за изработеното към Colibri® ERP, т.е. веднага след регистрирането й от работника. Нормално toDo е по-малко или равно на toDo_max.
Функциите GetActiveOpers, PutWork трябва да се изпъняват в този ред – циклично – (GetActiveOpers, PutWork); (GetActiveOpers, PutWork),...
След всяко изпълнение на PutWork се променят бройките за изпълнение за тройките ПК-операция-Сектор и последващото изпълнение на GetActiveOpers ще върне нови стойности за полетата toDo_max и toDo.
Всичко по детайлите на извикване на функцията GetActiveOpers е аналогично на функцията GetOperations.
Тук ще разгледаме пример за интерактивност между външна система за събиране на изработеното и въвеждането на информацията от нея в модул Производство на Colibri® ERP.
Нека имаме за даденост следната ПК, т.е. маршрут за производство:
Заработките по тази ПК ще бъдат вкарани автоматично с web service. По-надолу следват описания на запитването и отговора при изпълнението на този web service.
Примерен код за въвеждане на изпълнение от външна система изглежда по следния начин (PHP):
<?php include("../params.inc.php"); //include(PATH_INCLUDE."auth.inc.php"); //include(PATH_INCLUDE."basepage.inc.php"); include("nusoap.php"); // Entry point data $WS_URL = "https://dev3.edabg.com/erp/ws/wsbase.php?wsdl"; // Initializing client $sc = new nusoap_client($WS_URL, true); $err = $sc->getError(); if ($err) { echo "Constructor error $err\n"; } $sc->soap_defencoding = "UTF-8"; $sc->decode_utf8 = false; $sc->data_encoding = "UTF-8"; $sc->encode_utf8 = false; // Login използвайки потребител soap който е от тип web service $result = $sc->call("erpSOAPServer..Login", array("username" => "soap", "password" => "123")); echo "Calling ...<br>"; //------------------------------------------------------ // Test for function $result = $sc->call("erpSOAPProd..PutWork", //------------------------------------------------------ $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "П-002" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "1" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:05" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "ШЛ" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "3" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:10" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "END" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "1" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:15" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "П-002" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "1" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:20" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "П-001" , "idSector" => "" , "SectorNum" => "МТ-005" , "RefNum" => "00005" , "QuantityOK" => "3" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:25" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "П-002" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "3" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:30" ); $work[] = array( "idOperPersCard" => "" , "CNum" => "0002165" , "idOper" => "" , "ONum" => "END" , "idSector" => "" , "SectorNum" => "У-002" , "RefNum" => "00005" , "QuantityOK" => "2" , "QuantityWaste" => "" , "QuantityWasteSubj" => "" , "CompleteTime" => "11.01.2018 16:05:35" ); $result = $sc->call("erpSOAPProd..PutWork", array($work)); if ($sc->fault) { echo "Fault:<br>"; echo "<pre>".var_export($result,true)."</pre>"; } else { $err = $sc->getError(); if ($err) { echo "Error: $err<br>"; } else { echo "<pre>".var_export($result,true)."</pre>"; } } //------------------------------------------------------ // End of Test for function $result = $sc->call("erpSOAPProd..PutWork", //------------------------------------------------------ echo "<hr>Request<br>"; echo "<pre>"._h(var_export($sc->request,true))."</pre>"; echo "<hr>Response<br>"; echo "<pre>"._h(var_export($sc->response,true))."</pre>"; $result = $sc->call("erpSOAPServer..Logout"); ?>
При извикването на функцията PutWork с горепосочения код в ПК с номер 0002165, след тест за коректност на изпратените данни, се записват всички изпратени заработки.
Подаването на записите не изисква специална подредба. Функцията PutWork подрежда записите според реда на изпълнение, зададен в рецептата от съответната ПК и по времето на изпълнение (CompleteTime). Затова е необходимо всяка ПК да се разглежда като маршрутна карта за производство по една рецептура. След сортирането по ред на изпълнение следва сортиране по час на изпълнение – CompleteTime. Така записите за една и съща двойка операция-сектор (ONum-SectorNum) се подреждат и по време на изпълнение.
Нека да обърнем внимание на операция ONum = П-002 от кода. За нея има три записа за общо количество 5 изпълнения, т.е. изпратени са 5 изпълнения, въпреки, че по ПК е зададено да се изпълнят 3. Това е ситуация, при която се прави опит за преизпълнение и системата в отговора си връща информация за това несъответствие.
Резултатът в Colibri® ERP след изпълнение на запитването е следния:
Всички записи в таба Изпълнение на ПК съответстват точно на изпратената чрез разглеждания web service информация. Информацията е приета от Colibri® ERP и вече е обработена по съответния начин в ПК.
Ето как изглежда изпълнението по маршрута на разглежданата ПК:
Преизпълнението на операция с номер П-002 се вижда с отрицателното количество за изпълнение (-2).
Какво ще се предприеме нататък е въпрос на вътрешна организация във фирмата, но може да се открие къде е направено преизпълнение, да се коригира съответния запис или записи и отново да се изпълни запитването, за да се въведат заработките отново.
Функцията PutWork, която е в основата на разглеждания web service връща отговор на всяко запитване. Отговорът може да съдържа:
всички обработени без грешки записи допълнени с информационни полета toDo и Note;
toDo показва колко пъти остава да се изпълни операцията, след като е въведено текущото изпълнение;
Note = ‘OK’ когато изпълнението е въведено без да се нарушават изискванията за коректност. Иначе това поле съдържа информация за възможно несъответствие, която да е в помощ при обработката му;
Съобщения за грешно подадена или лисваща информация в данните;
Ето как изглежда основната част от отговора на разглежданото в нашия пример запитване:
Calling ... array ( 0 => array ( 'CNum' => '0002165', 'idOper' => 71, 'ONum' => 'П-001', 'idSector' => 28, 'SectorNum' => 'МТ-005', 'RefNum' => '00005', 'QuantityOK' => 3, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:25', 'toDo' => 0, 'Note' => 'OK', ), 1 => array ( 'CNum' => '0002165', 'idOper' => 72, 'ONum' => 'П-002', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 1, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:05', 'toDo' => 2, 'Note' => 'OK', ), 2 => array ( 'CNum' => '0002165', 'idOper' => 72, 'ONum' => 'П-002', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 1, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:20', 'toDo' => 1, 'Note' => 'OK', ), 3 => array ( 'CNum' => '0002165', 'idOper' => 72, 'ONum' => 'П-002', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 3, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:30', 'toDo' => -2, 'Note' => 'ПРЕДУПРЕЖДЕНИЕ! След обработка на записа има преизпълнение на операцията с 2!', ), 4 => array ( 'CNum' => '0002165', 'idOper' => 68, 'ONum' => 'ШЛ', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 3, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:10', 'toDo' => 2, 'Note' => 'OK', ), 5 => array ( 'CNum' => '0002165', 'idOper' => 83, 'ONum' => 'END', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 1, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:15', 'toDo' => 2, 'Note' => 'OK', ), 6 => array ( 'CNum' => '0002165', 'idOper' => 83, 'ONum' => 'END', 'idSector' => 2, 'SectorNum' => 'У-002', 'RefNum' => '00005', 'QuantityOK' => 2, 'QuantityWaste' => 0, 'QuantityWasteSubj' => 0, 'CompleteTime' => '11.01.2018 16:05:35', 'toDo' => 0, 'Note' => 'OK', ), )
Ако върнатия отговор е без съобщения за грешки или несъответствия, то информацията вече успешно е предадена в съответните ПК на модул производство в Colibri® ERP и е отразен направения напредък по производствените маршрути.
Ако е необходимо, т.е. върнати са съобщения за несъответствия, могат да бъдат предприети съответните действия за коригиране на грешно подадената информация и запитването да се изпрати отново.
Използването на web service може значително да автоматизира процеса по въвеждане на изпълнението по производствените маршрути като използвайки своите права за работа с Colibri® ERP, този web service периодично изпраща събраната информация към производствените карти в модул Производство.
Разбира се трябва да се разполага с външна система за регистриране на изпълненията, която притежава своята функционалност за електронно събиране на данни за изработеното от работниците.
За съвместната работа на Colibri® ERP и външната система за електронно събиране на заработките трябва да се синхронизират списъците на персонала (по полето RefNum с помощния web service PutWorkmen) и на тройките ПК-операции-работни центрове (GetActiveOpers) за активните в момента операции по стартираните и незавършени производствени маршрути.
Ако всички данни са в синхрон, работата на разглеждания web service ще бъде безпроблемна.