|
|
@@ -734,4 +734,158 @@ class OrderCgClearClass extends BaseClass
|
|
|
return array_values(array_unique(array_filter(array_map('intval', $arr))));
|
|
|
}
|
|
|
|
|
|
+ protected static function zeroAmountWhereSql($alias = '')
|
|
|
+ {
|
|
|
+ $prefix = $alias !== '' ? $alias . '.' : '';
|
|
|
+ return '(' . $prefix . 'amount IS NULL OR ' . $prefix . 'amount = 0 OR ' . $prefix . 'amount = \'0\' OR ' . $prefix . 'amount = \'0.00\')';
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function pairAmountKey($orderId, $cgId)
|
|
|
+ {
|
|
|
+ return intval($orderId) . '_' . intval($cgId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return array<string,string> orderId_cgId => amount
|
|
|
+ */
|
|
|
+ public static function buildPairAmountMap($clear)
|
|
|
+ {
|
|
|
+ $pairs = self::buildPairsFromClear($clear);
|
|
|
+ $map = [];
|
|
|
+ foreach ($pairs as $pair) {
|
|
|
+ $amount = self::normalizeAmount($pair['amount'] ?? 0);
|
|
|
+ if (bccomp($amount, '0', 2) <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $map[self::pairAmountKey($pair['orderId'] ?? 0, $pair['cgId'] ?? 0)] = $amount;
|
|
|
+ }
|
|
|
+ return $map;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function resolveAmountForRelationRow(array $row, array $pairAmountMap)
|
|
|
+ {
|
|
|
+ $orderId = intval($row['orderId'] ?? 0);
|
|
|
+ $cgId = intval($row['cgId'] ?? 0);
|
|
|
+ $key = self::pairAmountKey($orderId, $cgId);
|
|
|
+ if (isset($pairAmountMap[$key])) {
|
|
|
+ return $pairAmountMap[$key];
|
|
|
+ }
|
|
|
+ if ($cgId === 0 && $orderId > 0) {
|
|
|
+ $legacyKey = self::pairAmountKey(0, $orderId);
|
|
|
+ if (isset($pairAmountMap[$legacyKey])) {
|
|
|
+ return $pairAmountMap[$legacyKey];
|
|
|
+ }
|
|
|
+ $cg = PurchaseOrderClass::getById($orderId);
|
|
|
+ if (!empty($cg)) {
|
|
|
+ $amount = self::resolveDebtAmount($cg);
|
|
|
+ if (bccomp($amount, '0', 2) > 0) {
|
|
|
+ return $amount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($orderId > 0) {
|
|
|
+ $order = OrderClass::getById($orderId);
|
|
|
+ if (!empty($order)) {
|
|
|
+ $amount = self::resolveDebtAmount($order);
|
|
|
+ if (bccomp($amount, '0', 2) > 0) {
|
|
|
+ return $amount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($cgId > 0) {
|
|
|
+ $purchase = PurchaseClass::getById($cgId);
|
|
|
+ if (!empty($purchase)) {
|
|
|
+ $amount = self::resolveDebtAmount($purchase);
|
|
|
+ if (bccomp($amount, '0', 2) > 0) {
|
|
|
+ return $amount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $ghsCg = PurchaseOrderClass::getById($cgId);
|
|
|
+ if (!empty($ghsCg)) {
|
|
|
+ $amount = self::resolveDebtAmount($ghsCg);
|
|
|
+ if (bccomp($amount, '0', 2) > 0) {
|
|
|
+ return $amount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function countZeroAmountRelationRows()
|
|
|
+ {
|
|
|
+ $table = self::$baseFile::tableName();
|
|
|
+ return intval(Yii::$app->db->createCommand(
|
|
|
+ 'SELECT COUNT(*) FROM ' . $table . ' WHERE ' . self::zeroAmountWhereSql()
|
|
|
+ )->queryScalar());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return array[] id, clearId, orderId, cgId
|
|
|
+ */
|
|
|
+ public static function fetchZeroAmountRelationBatch($cursorId, $limit)
|
|
|
+ {
|
|
|
+ $table = self::$baseFile::tableName();
|
|
|
+ $sql = 'SELECT id, clearId, orderId, cgId FROM ' . $table
|
|
|
+ . ' WHERE ' . self::zeroAmountWhereSql();
|
|
|
+ $params = [];
|
|
|
+ if ($cursorId !== null) {
|
|
|
+ $sql .= ' AND id < :cursorId';
|
|
|
+ $params[':cursorId'] = intval($cursorId);
|
|
|
+ }
|
|
|
+ $sql .= ' ORDER BY id DESC LIMIT ' . intval($limit);
|
|
|
+ return Yii::$app->db->createCommand($sql)->bindValues($params)->queryAll();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param array[] $rows
|
|
|
+ * @return array{updated:int,skipped:int}
|
|
|
+ */
|
|
|
+ public static function patchZeroAmountRows(array $rows, $dryRun = false)
|
|
|
+ {
|
|
|
+ if (empty($rows)) {
|
|
|
+ return ['updated' => 0, 'skipped' => 0];
|
|
|
+ }
|
|
|
+ $clearIds = array_values(array_unique(array_filter(array_map('intval', array_column($rows, 'clearId')))));
|
|
|
+ $clearList = ClearClass::getAllByCondition(['id' => ['in', $clearIds]], null, '*', null);
|
|
|
+ $clearMap = [];
|
|
|
+ if (!empty($clearList)) {
|
|
|
+ foreach ($clearList as $clear) {
|
|
|
+ $id = is_array($clear) ? ($clear['id'] ?? 0) : ($clear->id ?? 0);
|
|
|
+ if ($id > 0) {
|
|
|
+ $clearMap[intval($id)] = $clear;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $pairMaps = [];
|
|
|
+ foreach ($clearIds as $clearId) {
|
|
|
+ if (isset($clearMap[$clearId])) {
|
|
|
+ $pairMaps[$clearId] = self::buildPairAmountMap($clearMap[$clearId]);
|
|
|
+ } else {
|
|
|
+ $pairMaps[$clearId] = [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $table = self::$baseFile::tableName();
|
|
|
+ $updated = 0;
|
|
|
+ $skipped = 0;
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ $relId = intval($row['id'] ?? 0);
|
|
|
+ $clearId = intval($row['clearId'] ?? 0);
|
|
|
+ if ($relId <= 0 || $clearId <= 0) {
|
|
|
+ $skipped++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $amount = self::resolveAmountForRelationRow($row, $pairMaps[$clearId] ?? []);
|
|
|
+ if ($amount === null || bccomp($amount, '0', 2) <= 0) {
|
|
|
+ $skipped++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!$dryRun) {
|
|
|
+ Yii::$app->db->createCommand()->update($table, ['amount' => $amount], ['id' => $relId])->execute();
|
|
|
+ }
|
|
|
+ $updated++;
|
|
|
+ }
|
|
|
+ return ['updated' => $updated, 'skipped' => $skipped];
|
|
|
+ }
|
|
|
+
|
|
|
}
|