source: trunk/Modules/Stock/Stock.php@ 894

Last change on this file since 894 was 894, checked in by chronos, 4 years ago
  • Modified: Further improved models initialization system.
File size: 16.7 KB
Line 
1<?php
2
3class ModuleStock extends AppModule
4{
5 function __construct(System $System)
6 {
7 parent::__construct($System);
8 $this->Name = 'Stock';
9 $this->Version = '1.0';
10 $this->Creator = 'Chronos';
11 $this->License = 'GNU/GPL';
12 $this->Description = 'Stock and products';
13 $this->Dependencies = array('User', 'Customer', 'Network');
14 }
15
16 function GetModels(): array
17 {
18 return array(Product::GetClassName(), StockSerialNumber::GetClassName(), Stock::GetClassName(),
19 StockMoveGroup::GetClassName(), StockMove::GetClassName(), StockMoveItem::GetClassName(),
20 StockItemHistory::GetClassName(), StockMoveItemSerialRel::GetClassName());
21 }
22
23 function DoStart(): void
24 {
25 global $Config;
26
27 $this->System->FormManager->RegisterClass('Product', array(
28 'Title' => 'Produkty',
29 'Table' => 'Product',
30 'DefaultSortColumn' => 'Name',
31 'Items' => array(
32 'Manufacturer' => array('Type' => 'TSubject', 'Caption' => 'Výrobce', 'Default' => '', 'Null' => true),
33 'Code' => array('Type' => 'String', 'Caption' => 'Kód', 'Default' => ''),
34 'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
35 'SellPrice' => array('Type' => 'Integer', 'Caption' => 'Prodejní cena', 'Default' => '0', 'Suffix' => 'Kč'),
36 'BuyPrice' => array('Type' => 'Integer', 'Caption' => 'Kupní cena', 'Default' => '0', 'Suffix' => 'Kč'),
37 'VAT' => array('Type' => 'Integer', 'Caption' => 'DPH', 'Default' => '0', 'Suffix' => '%'),
38 'Consumption' => array('Type' => 'Integer', 'Caption' => 'Spotřeba', 'Default' => '', 'Suffix' => 'Watt'),
39 'Supplier' => array('Type' => 'TSubject', 'Caption' => 'Dodavatel', 'Default' => '', 'Null' => true),
40 'UnitOfMeasure' => array('Type' => 'TUnitOfMeasure', 'Caption' => 'Měrná jednotka', 'Default' => '', 'Null' => true),
41 'StockSerialNumbers' => array('Type' => 'TStockSerialNumberListProduct', 'Caption' => 'Položky na skladě', 'Default' => ''),
42 'StockState' => array('Type' => 'Integer', 'Caption' => 'Počet na skladě', 'Default' => '', 'ReadOnly' => true,
43 'SQL' => 'SELECT IFNULL(SUM(`Amount`), 0) FROM `StockMoveItem` WHERE `StockMoveItem`.`Product`=#Id'),
44 'StockMinCount' => array('Type' => 'Integer', 'Caption' => 'Skladové minimum', 'Default' => '0'),
45 'StockMoves' => array('Type' => 'TStockMoveItemListProduct', 'Caption' => 'Pohyby na skladě', 'Default' => ''),
46 'NetworkDevices' => array('Type' => 'TNetworkDeviceListProduct', 'Caption' => 'Síťová zařízení', 'Default' => ''),
47 'StockShortage' => array('Type' => 'TStockState', 'Caption' => 'Stav skladu', 'Default' => '', 'ReadOnly' => true,
48 'SQL' => 'SELECT (IFNULL(SUM(`Amount`), 0) >= `StockMinCount`) FROM `StockMoveItem` WHERE `StockMoveItem`.`Product`=#Id'),
49 ),
50 ));
51
52 $this->System->FormManager->RegisterClass('StockSerialNumber', array(
53 'Title' => 'Skladové položky',
54 'Table' => 'StockSerialNumber',
55 'DefaultSortColumn' => 'Id',
56 'Items' => array(
57 'Stock' => array('Type' => 'TStock', 'Caption' => 'Sklad', 'Default' => ''),
58 'Product' => array('Type' => 'TProduct', 'Caption' => 'Produkt', 'Default' => ''),
59 'TimeEnlistment' => array('Type' => 'Date', 'Caption' => 'Datum zařazení', 'Default' => ''),
60 'TimeElimination' => array('Type' => 'Date', 'Caption' => 'Datum vyřazení', 'Default' => '', 'Null' => true),
61 'SellPrice' => array('Type' => 'Integer', 'Caption' => 'Prodejní cena', 'Default' => '0', 'Suffix' => 'Kč'),
62 'BuyPrice' => array('Type' => 'Integer', 'Caption' => 'Kupní cena', 'Default' => '0', 'Suffix' => 'Kč'),
63 'Amount' => array('Type' => 'Integer', 'Caption' => 'Množství', 'Default' => '1'),
64 'SerialNumber' => array('Type' => 'String', 'Caption' => 'Sériové číslo', 'Default' => '', 'Null' => true),
65 'RegNumber' => array('Type' => 'String', 'Caption' => 'Evidenční číslo', 'Default' => '', 'Null' => true),
66 'Location' => array('Type' => 'TMember', 'Caption' => 'Umístění', 'Default' => '', 'Null' => true),
67 'Esemble' => array('Type' => 'TStockSerialNumber', 'Caption' => 'Celek', 'Default' => ''),
68 'Parts' => array('Type' => 'TStockSerialNumberListStockSerialNumber', 'Caption' => 'Části', 'Default' => ''),
69 'History' => array('Type' => 'TStockItemHistoryListStockSerialNumber', 'Caption' => 'Historie', 'Default' => ''),
70 'Sériové čísla' => array('Type' => 'TStockMoveItemSerialListSerial', 'Caption' => 'Skladové pohyby', 'Default' => ''),
71 ),
72 ));
73 $this->System->FormManager->RegisterClass('Stock', array(
74 'Title' => 'Sklady',
75 'Table' => 'Stock',
76 'DefaultSortColumn' => 'Name',
77 'Items' => array(
78 'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
79 'Location' => array('Type' => 'TMember', 'Caption' => 'Umístění', 'Default' => '', 'Null' => true),
80 'Items' => array('Type' => 'TStockSerialNumberListStock', 'Caption' => 'Položky', 'Default' => ''),
81 'ItemsCount' => array('Type' => 'Integer', 'Caption' => 'Položek', 'Default' => '',
82 'ReadOnly' => true, 'SQL' => '(SELECT COUNT(*) FROM `StockSerialNumber` WHERE '.
83 '(`StockSerialNumber`.`Stock`=#Id) AND (`StockSerialNumber`.`TimeElimination` IS NULL))'),
84 'TotalPrice' => array('Type' => 'Integer', 'Caption' => 'Celková cena', 'Default' => '',
85 'ReadOnly' => true, 'SQL' => '(SELECT SUM(`SellPrice`) FROM `StockSerialNumber` WHERE '.
86 '(`StockSerialNumber`.`Stock`=#Id) AND (`StockSerialNumber`.`TimeElimination` IS NULL))', 'Suffix' => 'Kč'),
87 'Moves' => array('Type' => 'TStockMoveStock', 'Caption' => 'Pohyby', 'Default' => ''),
88 ),
89 ));
90 $this->System->FormManager->RegisterClass('StockMove', array(
91 'Title' => 'Skladový pohyb',
92 'Table' => 'StockMove',
93 'DefaultSortColumn' => 'Time',
94 'Items' => array(
95 'Group' => array('Type' => 'TStockMoveGroup', 'Caption' => 'Skupina', 'Default' => ''),
96 'BillCode' => array('Type' => 'TDocumentLineCode', 'Caption' => 'Označení', 'Default' => '', 'ReadOnly' => true),
97 'Time' => array('Type' => 'DateTime', 'Caption' => 'Čas', 'Default' => ''),
98 'Stock' => array('Type' => 'TStock', 'Caption' => 'Sklad', 'Default' => '', 'Null' => true),
99 'File' => array('Type' => 'TFile', 'Caption' => 'Doklad', 'Default' => '', 'Null' => true),
100 'Price' => array('Type' => 'Float', 'Caption' => 'Cena', 'Default' => '',
101 'ReadOnly' => true, 'Suffix' => 'Kč', 'SQL' => '(SELECT SUM(`StockMoveItem`.`UnitPrice` * `StockMoveItem`.`Amount`) FROM `StockMoveItem` '.
102 'WHERE `StockMoveItem`.`StockMove`=#Id)'),
103 'Items' => array('Type' => 'TStockMoveItemListStockMove', 'Caption' => 'Položky', 'Default' => ''),
104 ),
105 'BeforeInsert' => array($this, 'BeforeInsertStockMove'),
106 //'AfterInsert' => array($this, 'AfterInsertStockMove'),
107 //'BeforeModify' => array($this, 'BeforeModifyStockMove'),
108 ));
109 $this->System->FormManager->RegisterClass('StockMoveItem', array(
110 'Title' => 'Položka skladového pohybu',
111 'Table' => 'StockMoveItem',
112 'DefaultSortColumn' => 'Product',
113 'Items' => array(
114 'StockMove' => array('Type' => 'TStockMove', 'Caption' => 'Skladový pohyb', 'Default' => ''),
115 'Product' => array('Type' => 'TProduct', 'Caption' => 'Produkt', 'Default' => ''),
116 'UnitPrice' => array('Type' => 'Integer', 'Caption' => 'Jednotková cena', 'Default' => '0', 'Suffix' => 'Kč'),
117 'Amount' => array('Type' => 'Integer', 'Caption' => 'Množství', 'Default' => '1'),
118 'Total' => array('Type' => 'Integer', 'Caption' => 'Celkem', 'Default' => '', 'Suffix' => 'Kč',
119 'ReadOnly' => true, 'SQL' => 'ROUND(`UnitPrice` * `Amount`, '.$Config['Finance']['Rounding'].')'),
120 'Položky pohybů' => array('Type' => 'TStockMoveItemSerialListItem', 'Caption' => 'Vztahy sériových čísel', 'Default' => ''),
121 'Sériové čísla' => array('Type' => 'String', 'Caption' => 'Sériové čísla', 'ReadOnly' => true,
122 'SQL' => 'SELECT GROUP_CONCAT(`StockSerialNumber`.`RegNumber` SEPARATOR ", ") FROM `StockMoveItemSerialRel` '.
123 'LEFT JOIN `StockSerialNumber` ON `StockSerialNumber`.`Id`=`StockMoveItemSerialRel`.`StockSerialNumber` '.
124 'WHERE `StockMoveItemSerialRel`.`StockMoveItem`=#Id'),
125 ),
126 ));
127 $this->System->FormManager->RegisterClass('StockMoveGroup', array(
128 'Title' => 'Skupina skladových pohybů',
129 'Table' => 'StockMoveGroup',
130 'Items' => array(
131 'Name' => array('Type' => 'String', 'Caption' => 'Název', 'Default' => '0'),
132 'DocumentLine' => array('Type' => 'TDocumentLine', 'Caption' => 'Dokladová řada', 'Default' => '0'),
133 'ValueSign' => array('Type' => 'TFinanceValueSign', 'Caption' => 'Znaménko hodnoty', 'Default' => '0'),
134 'Direction' => array('Type' => 'TFinanceDirection', 'Caption' => 'Směr', 'Default' => '0'),
135 'Items' => array('Type' => 'TStockMoveListGroup', 'Caption' => 'Operace', 'Default' => ''),
136 ),
137 ));
138 $this->System->FormManager->RegisterClass('StockItemHistory', array(
139 'Title' => 'Historie skladové položky',
140 'Table' => 'StockItemHistory',
141 'DefaultSortColumn' => 'Time',
142 'Items' => array(
143 'Time' => array('Type' => 'DateTime', 'Caption' => 'Čas', 'Default' => ''),
144 'StockSerialNumber' => array('Type' => 'TStockSerialNumber', 'Caption' => 'Sériové číslo', 'Default' => ''),
145 'Text' => array('Type' => 'Text', 'Caption' => 'Text', 'Default' => ''),
146 ),
147 ));
148 $this->System->FormManager->RegisterClass('StockMoveItemSerialRel', array(
149 'Title' => 'Vztah položky skladových pohybů a sériových čísel',
150 'Table' => 'StockMoveItemSerialRel',
151 'Items' => array(
152 'StockMoveItem' => array('Type' => 'TStockMoveItem', 'Caption' => 'Položky pohybu', 'Default' => ''),
153 'StockSerialNumber' => array('Type' => 'TStockSerialNumber', 'Caption' => 'Sériové číslo', 'Default' => ''),
154 ),
155 ));
156 $this->System->FormManager->RegisterFormType('TStockMoveItemListStockMove', array(
157 'Type' => 'ManyToOne',
158 'Table' => 'StockMoveItem',
159 'Id' => 'Id',
160 'Ref' => 'StockMove',
161 'Filter' => '1',
162 ));
163 $this->System->FormManager->RegisterFormType('TStockMoveItemListProduct', array(
164 'Type' => 'ManyToOne',
165 'Table' => 'StockMoveItem',
166 'Id' => 'Id',
167 'Ref' => 'Product',
168 'Filter' => '1',
169 ));
170 $this->System->FormManager->RegisterFormType('TStockMoveListGroup', array(
171 'Type' => 'ManyToOne',
172 'Table' => 'StockMove',
173 'Id' => 'Id',
174 'Ref' => 'Group',
175 'Filter' => '1',
176 ));
177 $this->System->FormManager->RegisterFormType('TStockMoveStock', array(
178 'Type' => 'ManyToOne',
179 'Table' => 'StockMove',
180 'Id' => 'Id',
181 'Ref' => 'Stock',
182 'Filter' => '1',
183 ));
184 $this->System->FormManager->RegisterFormType('TStockMoveItemSerialListItem', array(
185 'Type' => 'ManyToOne',
186 'Table' => 'StockMoveItemSerialRel',
187 'Id' => 'Id',
188 'Ref' => 'StockMoveItem',
189 'Filter' => '1',
190 ));
191 $this->System->FormManager->RegisterFormType('TStockMoveItemSerialListSerial', array(
192 'Type' => 'ManyToOne',
193 'Table' => 'StockMoveItemSerialRel',
194 'Id' => 'Id',
195 'Ref' => 'StockSerialNumber',
196 'Filter' => '1',
197 ));
198 $this->System->FormManager->RegisterFormType('TStockMove', array(
199 'Type' => 'Reference',
200 'Table' => 'StockMove',
201 'Id' => 'Id',
202 'Name' => '(SELECT `DocumentLineCode`.`Name` FROM `DocumentLineCode` WHERE `Id`=`StockMove`.`BillCode`)',
203 'Filter' => '1',
204 ));
205 $this->System->FormManager->RegisterFormType('TStockMoveItem', array(
206 'Type' => 'Reference',
207 'Table' => 'StockMoveItem',
208 'Id' => 'Id',
209 'Name' => '(SELECT `Name` FROM `Product` WHERE `Product`.`Id`=`StockMoveItem`.`Product`)',
210 'Filter' => '1',
211 ));
212 $this->System->FormManager->RegisterFormType('TProduct', array(
213 'Type' => 'Reference',
214 'Table' => 'Product',
215 'Id' => 'Id',
216 'Name' => 'Name',
217 'Filter' => '1',
218 ));
219 $this->System->FormManager->RegisterFormType('TStock', array(
220 'Type' => 'Reference',
221 'Table' => 'Stock',
222 'Id' => 'Id',
223 'Name' => 'Name',
224 'Filter' => '1',
225 ));
226 $this->System->FormManager->RegisterFormType('TStockMoveGroup', array(
227 'Type' => 'Reference',
228 'Table' => 'StockMoveGroup',
229 'Id' => 'Id',
230 'Name' => 'Name',
231 'Filter' => '1',
232 ));
233 $this->System->FormManager->RegisterFormType('TStockSerialNumber', array(
234 'Type' => 'Reference',
235 'Table' => 'StockSerialNumber',
236 'Id' => 'Id',
237 'Name' => 'RegNumber',
238 'Filter' => '1',
239 ));
240 $this->System->FormManager->RegisterFormType('TStockItemHistoryListStockSerialNumber', array(
241 'Type' => 'ManyToOne',
242 'Table' => 'StockItemHistory',
243 'Id' => 'Id',
244 'Ref' => 'StockSerialNumber',
245 'Filter' => '1',
246 ));
247
248 $this->System->FormManager->RegisterFormType('TStockState', array(
249 'Type' => 'Enumeration',
250 'States' => array('<span style="color:red;">Nedostatek</span>',
251 '<span style="color:green;">Dostatek</span>'),
252 ));
253 }
254
255 function BeforeInsertStockMove(Form $Form): array
256 {
257 $Finance = &ModuleFinance::Cast($this->System->GetModule('Finance'))->Finance;
258 if (array_key_exists('Time', $Form->Values)) $Year = date("Y", $Form->Values['Time']);
259 else $Year = date("Y", $Form->Values['ValidFrom']);
260 $Group = $Finance->GetFinanceGroupById($Form->Values['Group'], 'StockMoveGroup');
261 $Form->Values['BillCode'] = $Finance->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
262 return $Form->Values;
263 }
264}
265
266class Product extends Model
267{
268 static function GetDesc(): ModelDesc
269 {
270 $Desc = new ModelDesc(self::GetClassName());
271 $Desc->AddReference('Manufacturer', Subject::GetClassName());
272 $Desc->AddString('Code');
273 $Desc->AddString('Name');
274 $Desc->AddInteger('SellPrice');
275 $Desc->AddInteger('BuyPrice');
276 $Desc->AddInteger('VAT');
277 $Desc->AddInteger('Consumption');
278 $Desc->AddReference('Supplier', Subject::GetClassName());
279 $Desc->AddReference('UnitOfMeasure', UnitOfMeasure::GetClassName());
280 $Desc->AddInteger('StockMinCount');
281 return $Desc;
282 }
283}
284
285class StockSerialNumber extends Model
286{
287 static function GetDesc(): ModelDesc
288 {
289 $Desc = new ModelDesc(self::GetClassName());
290 $Desc->AddReference('Stock', Stock::GetClassName());
291 $Desc->AddReference('Product', Product::GetClassName());
292 $Desc->AddDate('TimeEnlistment');
293 $Desc->AddDate('TimeElimination');
294 $Desc->AddInteger('SellPrice');
295 $Desc->AddInteger('BuyPrice');
296 $Desc->AddInteger('Amount');
297 $Desc->AddString('SerialNumber');
298 $Desc->AddString('RegNumber');
299 $Desc->AddReference('Location', Member::GetClassName());
300 $Desc->AddReference('Esemble', StockSerialNumber::GetClassName());
301 return $Desc;
302 }
303}
304
305class Stock extends Model
306{
307 static function GetDesc(): ModelDesc
308 {
309 $Desc = new ModelDesc(self::GetClassName());
310 $Desc->AddReference('Location', Member::GetClassName());
311 return $Desc;
312 }
313}
314
315class StockMove extends Model
316{
317 static function GetDesc(): ModelDesc
318 {
319 $Desc = new ModelDesc(self::GetClassName());
320 $Desc->AddReference('Group', StockMoveGroup::GetClassName());
321 $Desc->AddDateTime('Time');
322 $Desc->AddReference('Stock', Stock::GetClassName());
323 $Desc->AddReference('File', File::GetClassName());
324 return $Desc;
325 }
326}
327
328class StockMoveItem extends Model
329{
330 static function GetDesc(): ModelDesc
331 {
332 $Desc = new ModelDesc(self::GetClassName());
333 $Desc->AddReference('StockMove', StockMove::GetClassName());
334 $Desc->AddReference('Product', Product::GetClassName());
335 $Desc->AddInteger('UnitPrice');
336 $Desc->AddInteger('Amount');
337 return $Desc;
338 }
339}
340
341class StockMoveGroup extends Model
342{
343 static function GetDesc(): ModelDesc
344 {
345 $Desc = new ModelDesc(self::GetClassName());
346 $Desc->AddString('Name');
347 $Desc->AddReference('DocumentLine', DocumentLine::GetClassName());
348 $Desc->AddInteger('ValueSign');
349 $Desc->AddInteger('Direction');
350 return $Desc;
351 }
352}
353
354class StockItemHistory extends Model
355{
356 static function GetDesc(): ModelDesc
357 {
358 $Desc = new ModelDesc(self::GetClassName());
359 $Desc->AddDateTime('Time');
360 $Desc->AddReference('StockSerialNumber', StockSerialNumber::GetClassName());
361 $Desc->AddText('Text');
362 return $Desc;
363 }
364}
365
366class StockMoveItemSerialRel extends Model
367{
368 static function GetDesc(): ModelDesc
369 {
370 $Desc = new ModelDesc(self::GetClassName());
371 $Desc->AddReference('StockMoveItem', StockMoveItem::GetClassName());
372 $Desc->AddReference('StockSerialNumber', StockSerialNumber::GetClassName());
373 return $Desc;
374 }
375}
Note: See TracBrowser for help on using the repository browser.