/** * @param OperatorXML $xml * @return Report|null */ public static function generate(OperatorXML $xml) { $operator = Operator::findOne(['contract' => $xml->getContract()]); $operatorId = $operator !== null ? $operator->getPrimaryKey() : null; $period = ['month' => $xml->getMonth(), 'year' => $xml->getYear()]; $report = self::findOne(['operatorId' => $operatorId, 'period' => $period]); if (!$report instanceof Report) { $report = new Report(); $report['operatorId'] = $operatorId; $report['period'] = $period; } else { $report->outSideDb = []; $report->outSideOperator = []; } if (!$report->save()) { return null; } $report->unlinkAll('items', true); $outSideOperator = Number::find()->where(['operatorId' => $report->operatorId])->indexBy('number')->all(); $outSideDB = []; foreach ($xml->getItems() as $item) { $number = $item['number']; if (array_key_exists($number, $outSideOperator)) { $report->addItem($outSideOperator[$number], $item['expenditure']); unset($outSideOperator[$number]); } else { $outSideDB[] = $item; } } $report->outSideOperator = array_map(function ($item) { return ['number' => $item->number, 'id' => $item->getPrimaryKey()]; }, array_values($outSideOperator)); $report->outSideDb = $outSideDB; $report->save(false); return $report; }